从两个x,y点和一个中心x,y点在画布上绘制弧形

4

我想从两个点(X,Y坐标)画一条弧线。

但是我无法找出如何指定起始角度和结束角度的方法。

我有中心点(p2),半径为r。起始点(p1)和结束点(p3)如下所示 What I have

我想要做的是使用弧线来画一个圆形轮廓,如下所示

What I wanna have

我在这个主题上找到的所有内容都只是从0到大约2*Math.PI绘制弧线的示例。

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

像这样。我想不出如何使用p1和p3代替那些数字。有人能解释一下这是如何工作的,或者给我一个解决方法吗?


从p2到p1和从p2到p3的距离总是相同的吗? - user1693593
是的,半径将始终相同。 - DaCh
2个回答

7
arc() 方法只能使用角度,因此必须根据点的位置和到中心的距离进行转换(在这种情况下,距离表示半径,两者必须相同)。 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);

假设已知半径,这些现在可以被输入到arc方法中:

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

如果半径未知但已知相同,则可以执行以下操作: ```html

如果半径未知但已知相同,则可以执行以下操作:

```
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>

没有辅助线的结果

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>


这就是它。只是一个小问题,我能否通过从圆心画一条线来实现这个?我只想要圆形线。 - DaCh
@DaCh 当然,它们只是用来说明原始数据基础的。只需忽略最后一个代码块(// 点 / 线辅助工具...及以下)。 (仅添加弧段片段) - user1693593

0
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)

设m23为连接点3(x3,y3)和点2(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)

不确定我是否理解你的意思,我想要做的是获取我的p1和p2的起始角度和结束角度。我不明白你在这个例子中是如何得到它的。 - DaCh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接