C# 用 3 个点绘制圆弧 [英] C# Drawing Arc with 3 Points

查看:39
本文介绍了C# 用 3 个点绘制圆弧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用 GraphicsPath 绘制一条弧线,并具有初始点、中间点和最终点.弧线必须通过他们.

I need to draw an arc using GraphicsPath and having initial, median and final points. The arc has to pass on them.

我尝试了 .DrawCurve 和 .DrawBezier 但结果不完全是弧形.

I tried .DrawCurve and .DrawBezier but the result isn't exactly an arc.

我能做什么?

解决方案:

经过几个小时的代码编写,我设法用这个算法画出了我想要的东西(给出 3 个点 a、b、c 和一个 GraphicsPath 路径):

After a couple of hours of code writing I managed to draw what I wanted with this algorithm (give 3 Point a,b,c and a GraphicsPath path):

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按积分.

I would use DrawArc() as suggested by ANC_Michael. To find an arc that passes through 3 points you want to calculate the circumcircle of the triangle formed by the points.

一旦您有了外接圆,就可以使用最小/最大尺寸(中心 +/- 半径)计算要与 DrawArc 一起使用的圆的边界框.现在通过平移点来计算起始角和停止角,使外接圆以原点为中心(通过 -circumcenter 平移)并取标准化起始向量和终止向量与 X 轴的点积:

Once you have the circumcircle calculate a bounding box for the circle to use with DrawArc using the min/max dimensions (center +/- radius). Now calculate your start and stop angles by translating the points so that the circumcircle is centered on the origin (translate by -circumcenter) and take the dot-product of the normalized start and end vectors with the X-axis:

double startAngle = Math.Acos(VectorToLeftPoint.Dot(XAxis));
double stopAngle = Math.Acos(VectorToRightPoint.Dot(XAxis));

请注意,DrawArc 期望与 X 轴呈顺时针角度,因此如果计算出的向量高于 x 轴,您应该添加 Math.PI.这应该足以调用DrawArc().

Note that DrawArc expects angles clockwise from the X-axis so you should add Math.PI if the calculated vector is above the x-axis. That should be enough information to call DrawArc().

此方法将找到圆形弧,但不一定是最适合"的弧,具体取决于您预期的端点行为.

This method will find a circular arc and not necessarily the 'best fit' arc depending on your expected endpoint behavior.

这篇关于C# 用 3 个点绘制圆弧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆