我需要使用graphicspath绘制一个弧,并有初始点、中间点和最终点。弧线必须穿过它们。
我试过了,拉曲线和拉贝塞尔,但结果不是一个弧。
我能做什么?
解决方案:
在几个小时的代码编写之后,我用这个算法画出了我想要的东西(给出3个点a,b,c和一个graphicspath路径):
double d = 2 * (a.X - c.X) * (c.Y - b.Y) + 2 * (b.X - c.X) * (a.Y - c.Y);
double m1 = (Math.Pow(a.X, 2) - Math.Pow(c.X, 2) + Math.Pow(a.Y, 2) - Math.Pow(c.Y, 2));
double m2 = (Math.Pow(c.X, 2) - Math.Pow(b.X, 2) + Math.Pow(c.Y, 2) - Math.Pow(b.Y, 2));
double nx = m1 * (c.Y - b.Y) + m2 * (c.Y - a.Y);
double ny = m1 * (b.X - c.X) + m2 * (a.X - c.X);
double cx = nx / d;
double cy = ny / d;
double dx = cx - a.X;
double dy = cy - a.Y;
double distance = Math.Sqrt(dx * dx + dy * dy);
Vector va = new Vector(a.X - cx, a.Y - cy);
Vector vb = new Vector(b.X - cx, b.Y - cy);
Vector vc = new Vector(c.X - cx, c.Y - cy);
Vector xaxis = new Vector(1, 0);
float startAngle = (float)Vector.AngleBetween(xaxis, va);
float sweepAngle = (float)(Vector.AngleBetween(va, vb) + Vector.AngleBetween(vb, vc));
path.AddArc(
(float)(cx - distance), (float)(cy - distance),
(float)(distance * 2), (float)(distance * 2),
startAngle, sweepAngle);
最佳答案
我会按照anc_michael的建议使用DrawArc()
。若要查找通过3个点的圆弧,则需要计算由这些点构成的三角形的circumcircle。
一旦有了外接圆,使用最小/最大尺寸(中心+/-半径)计算圆的边界框,以便与DrawArc
一起使用。现在,通过平移点来计算起点和终点角度,使外接圆以原点为中心(按外接圆平移),并采用带X轴的标准化起点和终点向量的点积:
double startAngle = Math.Acos(VectorToLeftPoint.Dot(XAxis));
double stopAngle = Math.Acos(VectorToRightPoint.Dot(XAxis));
请注意,
DrawArc
需要从x轴顺时针方向的角度,因此如果计算出的向量高于x轴,则应添加Math.PI
。这些信息应该足够调用DrawArc()
。编辑:根据预期的端点行为,此方法将查找圆弧,而不一定是“最佳拟合”圆弧。