【问题标题】:Draw arc on canvas from two x, y points and a center x, y point从两个 x, y 点和一个中心 x, y 点在画布上绘制弧线
【发布时间】:2015-07-06 14:13:59
【问题描述】:

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

但我不知道该怎么做,所以我可以指定开始角度和结束角度

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

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

我在这个主题上发现的只是弧线从 0 绘制到 2*Math.PI 之类的示例。

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

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

【问题讨论】:

  • p2到p1和p2到p3的距离总是一样吗?
  • 是的,半径总是一样的

标签: javascript html5-canvas trigonometry


【解决方案1】:

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

signature of arc() 是:

void arc(unrestricted double x,
不受限制的双 y,
不受限制的双半径,
不受限制的双起始角度,
不受限制的双端角,
可选布尔逆时针=假);

你可以通过简单的三角函数找到从中心 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);

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

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/辅助行

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 当然,他们只是为了说明原始数据基础。只需忽略最后一个代码块(// 点/行助手......及以下)。 (只为弧添加了 sn-p)
【解决方案2】:
ctx.arc(100,75,50,0,2*Math.PI);

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

设m21为point1(x1, y1)和point2(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)

【讨论】:

  • 不确定我是否明白你所说的,我想要做的是获取我的 p1 和 p2 的起始角度和结束角度。在这个例子中不明白你是如何得到它的
猜你喜欢
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多