从两个 x、y 点和一个中心 x、y 点在 canvas 上绘制圆弧

Draw arc on canvas from two x, y points and a center x, y point

我正在尝试从两点(X、​​Y 线)绘制弧线。

但我想不出如何指定开始角度和结束角度

我得到了中心点(p2),半径= r。起点(p1)和终点(p3)。 如下图所示

而我想做的是用圆弧画一条圆线,如下所示

我在这个主题上发现的只是一个例子,其中弧从 0 绘制到类似 2*Math.PI.

ctx.arc(100,75,50,0,2*Math.PI);

像这样。 A 想不出可以使用 p1 和 p3 代替这些数字的方法。任何人都可以解释这是如何工作的,也许可以告诉我如何解决这个问题?

ctx.arc(100,75,50,0,2*Math.PI);

这里前两个参数是点p2的x,y坐标,第三个参数是圆r的半径。 第四个和第五个参数是圆弧的起始角和结束角。

设 m21 为连接点 1(x1, y1) 和点 2(x2, y2) 的直线的斜率

m21 = (y2-y1)/(x2-x1)

设m21为连接point3(x3, y3)和point2(x2, y2)的直线的斜率

m23 = (y2-y3)/(x2-x3)

ctx.arc(100, 75, 50, Math.atan(m21), Math.atan(m23), true)

会的。

如果 point2 是原点,那么解决方案更简单。

ctx.arc(100, 75, 50, Math.atan2(x1,y1), Math.atan2(x3,y3), true)

arc() 方法仅适用于角度,因此点必须根据它们的位置和到中心的距离进行转换(距离,表示半径,在这种情况下两者必须相同)。

signature of arc()是:

void arc(unrestricted double x,
              unrestricted double y,
              unrestricted double radius,
              unrestricted double startAngle,
              unrestricted double endAngle,
              optional boolean anticlockwise = false);

你可以用简单的三角函数求出中心P2到P1/P3的两个角:

var startAngle = Math.atan2(p1.y - p2.y, p1.x - p2.x),
    endAngle   = Math.atan2(p3.y - p2.y, p3.x - p2.x);

假设半径已知,现在可以将这些输入弧法:

ctx.arc(p2.x, p2.y, radius, startAngle, endAngle);

如果半径未知但已知相同,您可以这样做:

var diffX = p1.x - p2.x,
    diffY = p1.y - p2.y,
    radius = Math.abs(Math.sqrt(diffX*diffX + diffY*diffY));

例子

var p2 = {x: 100   , y: 100   },
    p1 = {x: 111, y:  30.9},
    p3 = {x: 149.5 , y:  149.5},
    diffX = p1.x - p2.x,
    diffY = p1.y - p2.y,
    radius = Math.abs(Math.sqrt(diffX*diffX + diffY*diffY)),
    startAngle = Math.atan2(diffY, diffX),
    endAngle   = Math.atan2(p3.y - p2.y, p3.x - p2.x),
    ctx = document.querySelector("canvas").getContext("2d");

// arc
ctx.arc(p2.x, p2.y, radius, startAngle, endAngle, false);
ctx.stroke();

// points / lines helpers:
ctx.fillRect(p1.x - 2, p1.y - 2, 4, 4);
ctx.fillRect(p2.x - 2, p2.y - 2, 4, 4);
ctx.fillRect(p3.x - 2, p3.y - 2, 4, 4);
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.x);
ctx.lineTo(p3.x, p3.x);
ctx.strokeStyle = "#999";
ctx.stroke();
<canvas height=180></canvas>

结果wo/helper行

var p2 = {x: 100   , y: 100   },
    p1 = {x: 111, y:  30.9},
    p3 = {x: 149.5 , y:  149.5},
    diffX = p1.x - p2.x,
    diffY = p1.y - p2.y,
    radius = Math.abs(Math.sqrt(diffX*diffX + diffY*diffY)),
    startAngle = Math.atan2(diffY, diffX),
    endAngle   = Math.atan2(p3.y - p2.y, p3.x - p2.x),
    ctx = document.querySelector("canvas").getContext("2d");

// arc
ctx.arc(p2.x, p2.y, radius, startAngle, endAngle, false);
ctx.stroke();
<canvas height=180></canvas>