Нарисуйте дугу с помощью bezierCurveTo с относительными координатами точек дуги

Я даже не уверен, что правильно спрашиваю. Это для рисования плана этажа, и прямо сейчас у меня есть линии с подвижными точками на каждом конце, поэтому холст интерактивен. Я хочу использовать кривую, чтобы создать дугу дверного проема, которая будет нарисована по этой линии. У меня есть начальная и конечная точка из существующего кода, где начинается и заканчивается кривая, но элементы управления дугой относятся к определенной координате, которая не вычисляется, поэтому дуга никогда не идет туда, куда должна.

Это то, что у меня есть прямо сейчас, я узнал, что moveTo() и lineTo() управляют его начальной и конечной точкой. Спасибо за помощь, никогда раньше не игрался с холстами

activeLineDrawing.beginPath();
activeLineDrawing.moveTo(lineSegments[lineSeg].panels[i].getX2(),lineSegments[lineSeg].panels[i].getY2());
activeLineDrawing.lineTo(lineSegments[lineSeg].panels[i].getX1(),lineSegments[lineSeg].panels[i].getY1());
activeLineDrawing.bezierCurveTo(100, 75, 50, 1, lineSegments[lineSeg].panels[i].getX2(),lineSegments[lineSeg].panels[i].getY2());
activeLineDrawing.fillStyle = 'lightgrey';
activeLineDrawing.strokeStyle = 'lightgrey';
activeLineDrawing.stroke();
activeLineDrawing.closePath();

person Stephen Mangopoulos    schedule 14.08.2018    source источник
comment
Вы пробовали с дугой, как я упоминал в своем ответе?   -  person Helder Sepulveda    schedule 22.08.2018
comment
Эй, извини! спасибо за ответ, он мне очень помог, но все еще немного борется здесь. это дает мне правильную форму, предполагающую горизонтальную линию между точками, но, поскольку мои начальные и конечные точки находятся в переменном месте, поэтому они могут быть под любым углом, а нарисованные ворота останутся на месте и будут выглядеть странно. Я пытаюсь поиграть с функцией поворота, но это борьба.   -  person Stephen Mangopoulos    schedule 23.08.2018
comment
Я внес некоторые изменения в свой ответ ... переместите код, чтобы он функционировал, и нарисуйте диагональный дверной проем ... Вам просто нужно поиграть с начальными и конечными углами.   -  person Helder Sepulveda    schedule 23.08.2018
comment
Если у вас есть более сложные сценарии, создайте правильный фрагмент, воспроизводящий вашу проблему.   -  person Helder Sepulveda    schedule 23.08.2018
comment
Я думаю, что последняя версия сделала это для вас...   -  person Helder Sepulveda    schedule 24.08.2018
comment
Привет, спасибо, на самом деле я еще не пробовал, но я посмотрел на ваш ответ, и он имел для меня логический смысл, поэтому я думаю, что это сработает, я отпишусь позже, чтобы поделиться рабочим решением. Спасибо!   -  person Stephen Mangopoulos    schedule 25.08.2018


Ответы (1)


Попробуйте с обычной дугой, вот пример кода

function drawDoor(ctx, color, sx, sy, ex, ey, offset) {
  var mx = (sx + (sx + ex) / 2) /2
  var my = (sy + (sy + ey) / 2) /2
  var iniAng = Math.atan2(ey-sy, ex-sx)/Math.PI - offset;
  var endAng = (iniAng + offset);
  
  ctx.beginPath();
  ctx.moveTo(sx, sy);  
  ctx.strokeStyle = color;
  ctx.lineWidth=3;
  ctx.lineTo(mx, my);  
  ctx.arc(mx, my, 45, iniAng * Math.PI, endAng * Math.PI, offset<0);
  ctx.lineTo(ex, ey);
  ctx.stroke();
  ctx.closePath();
}

var canvas = document.getElementById("canvas");
var activeLineDrawing = canvas.getContext("2d");


// Door opening to the left
drawDoor(activeLineDrawing, "black", 180, 60, 270, 60, 0.5);

// Door opening to the right
drawDoor(activeLineDrawing, "red", 200, 100, 290, 100, -0.5);

// Diagonal door opening right
drawDoor(activeLineDrawing, "blue", 20, 20, 75, 80, -0.5);

// Diagonal door opening left
drawDoor(activeLineDrawing, "green", 50, 30, 140, 90, 0.5);

// Closet doors double opening
drawDoor(activeLineDrawing, "cyan", 145, 30, 145, 90, 0.25);
drawDoor(activeLineDrawing, "cyan", 145, 150, 145, 90, -0.25);
<canvas id="canvas" width="300" height="150"></canvas>

Я рекомендую потратить некоторое время на чтение и понимание математики того, что я здесь делаю, то же самое можно применить во многих других местах.

person Helder Sepulveda    schedule 14.08.2018