从两个 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()
方法仅适用于角度,因此点必须根据它们的位置和到中心的距离进行转换(距离,表示半径,在这种情况下两者必须相同)。
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>
我正在尝试从两点(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()
方法仅适用于角度,因此点必须根据它们的位置和到中心的距离进行转换(距离,表示半径,在这种情况下两者必须相同)。
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>