如何绘制通过 3 个点的圆弧?
How to plot arc that passes through 3 points?
我正在尝试绘制一条通过给定 3 个控制点(即 [P1,P2,P3]
)的圆弧。我找到了圆方程和上面的点的角度。但是,我无法确定方向(CCW,CW)。我得到了这样的错误结果:
黄色弧线显然在另一边。我对处理这个 angular 问题的解决方案或直接通过 3 个点生成弧的程序持开放态度。
请注意绿色曲线与问题无关。
考虑了所有的可能性,我最终写了一个生成弧线通过3个点的代码。这里是thetaStart和thetaEnd角度的计算;
function obj = fitArc(obj,points)
x1 = points(1,1);
x2 = points(2,1);
x3 = points(3,1);
y1 = points(1,2);
y2 = points(2,2);
y3 = points(3,2);
A = x1*(y2-y3)-y1*(x2-x3)+x2*y3-x3*y2;
B = (x1^2+y1^2)*(y3-y2)+(x2^2+y2^2)*(y1-y3)+(x3^2+y3^2)*(y2-y1);
C = (x1^2+y1^2)*(x2-x3)+(x2^2+y2^2)*(x3-x1)+(x3^2+y3^2)*(x1-x2);
D = (x1^2+y1^2)*(x3*y2-x2*y3)+(x2^2+y2^2)*(x1*y3-x3*y1)+(x3^2+y3^2)*(x2*y1-x1*y2);
obj.x = -B/(2*A);
obj.y = -C/(2*A);
obj.r = sqrt((B^2+C^2-4*A*D)/(4*A^2));
th1 = wrapTo2Pi(atan2((points(3,2)-obj.y),(points(3,1)-obj.x)));
th3 = wrapTo2Pi(atan2((points(1,2)-obj.y),(points(1,1)-obj.x)));
th2 = wrapTo2Pi(atan2((points(2,2)-obj.y),(points(2,1)-obj.x)));
if (th1 < th2 && th2 < th3)
obj.thStart = th1;
obj.thEnd = th3;
elseif (th1<th3 && th3<th2)
obj.thStart = th3;
obj.thEnd = th1+2*pi;
elseif (th2<th1 && th1<th3)
obj.thStart = th3;
obj.thEnd = th1+2*pi;
elseif (th2<th3 && th3<th1)
obj.thStart = th1;
obj.thEnd = th3+2*pi;
elseif (th3<th1 && th1<th2)
obj.thStart = th1;
obj.thEnd = th3+2*pi;
elseif (th3 < th2 && th2 < th1)
obj.thStart = th3;
obj.thEnd = th1;
end
end
找到起始角和结束角后,绘图函数应如下所示:
th = linspace(thStart,thEnd,n);
xunit = r * cos(th) + x;
yunit = r * sin(th) + y;
plot(xunit, yunit,'linewidth',3);
这里是随机测试;
我希望这个解决方案能帮助很多人,因为我看到了很多关于这个问题的悬而未决的问题。
我正在尝试绘制一条通过给定 3 个控制点(即 [P1,P2,P3]
)的圆弧。我找到了圆方程和上面的点的角度。但是,我无法确定方向(CCW,CW)。我得到了这样的错误结果:
黄色弧线显然在另一边。我对处理这个 angular 问题的解决方案或直接通过 3 个点生成弧的程序持开放态度。
请注意绿色曲线与问题无关。
考虑了所有的可能性,我最终写了一个生成弧线通过3个点的代码。这里是thetaStart和thetaEnd角度的计算;
function obj = fitArc(obj,points)
x1 = points(1,1);
x2 = points(2,1);
x3 = points(3,1);
y1 = points(1,2);
y2 = points(2,2);
y3 = points(3,2);
A = x1*(y2-y3)-y1*(x2-x3)+x2*y3-x3*y2;
B = (x1^2+y1^2)*(y3-y2)+(x2^2+y2^2)*(y1-y3)+(x3^2+y3^2)*(y2-y1);
C = (x1^2+y1^2)*(x2-x3)+(x2^2+y2^2)*(x3-x1)+(x3^2+y3^2)*(x1-x2);
D = (x1^2+y1^2)*(x3*y2-x2*y3)+(x2^2+y2^2)*(x1*y3-x3*y1)+(x3^2+y3^2)*(x2*y1-x1*y2);
obj.x = -B/(2*A);
obj.y = -C/(2*A);
obj.r = sqrt((B^2+C^2-4*A*D)/(4*A^2));
th1 = wrapTo2Pi(atan2((points(3,2)-obj.y),(points(3,1)-obj.x)));
th3 = wrapTo2Pi(atan2((points(1,2)-obj.y),(points(1,1)-obj.x)));
th2 = wrapTo2Pi(atan2((points(2,2)-obj.y),(points(2,1)-obj.x)));
if (th1 < th2 && th2 < th3)
obj.thStart = th1;
obj.thEnd = th3;
elseif (th1<th3 && th3<th2)
obj.thStart = th3;
obj.thEnd = th1+2*pi;
elseif (th2<th1 && th1<th3)
obj.thStart = th3;
obj.thEnd = th1+2*pi;
elseif (th2<th3 && th3<th1)
obj.thStart = th1;
obj.thEnd = th3+2*pi;
elseif (th3<th1 && th1<th2)
obj.thStart = th1;
obj.thEnd = th3+2*pi;
elseif (th3 < th2 && th2 < th1)
obj.thStart = th3;
obj.thEnd = th1;
end
end
找到起始角和结束角后,绘图函数应如下所示:
th = linspace(thStart,thEnd,n);
xunit = r * cos(th) + x;
yunit = r * sin(th) + y;
plot(xunit, yunit,'linewidth',3);
这里是随机测试;
我希望这个解决方案能帮助很多人,因为我看到了很多关于这个问题的悬而未决的问题。