C#绘制弧连得3分 [英] C# Drawing Arc with 3 Points

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

问题描述

我需要使用GraphicsPath的并具有初始,中间和最终指向划出一道弧线。电弧必须通过他们。



我试过.DrawCurve和.DrawBezier但结果是不完全的弧线。



我能做些什么



解决方案:



在一对夫妇的代码编写的时间我设法画什么,我想用这个算法(给予3点A,b,C和A GraphicsPath的路径):

 双D = 2 *(AX  -  CX)*(CY  -  BY)+ 2 *(BX  -  CX)*(AY  -  CY); 
双M1 =(Math.Pow(a.X,2) - Math.Pow(c.X,2)+ Math.Pow(a.Y,2) - Math.Pow(c.Y,2));
双M2 =(Math.Pow(c.X,2) - Math.Pow(b.X,2)+ Math.Pow(c.Y,2) - Math.Pow(b.Y,2));
双NX = M1 *(c.Y - b.Y)+ 2 *(c.Y - a.Y);
双NY = M1 *(b.X - c.X)+ 2 *(a.X - c.X);
双CX = NX /天;
双CY = NY /天;
双DX = CX - a.X;
双DY = CY - a.Y;
双距离=的Math.sqrt(DX * DX + DY * DY);
矢量VA =新的向量(a.X - CX,a.Y - CY);
向量V =新的向量(b.X - CX,b.Y - CY);
矢量Vc =新的向量(c.X - CX,c.Y - CY);
矢量x轴=新的向量(1,0);
浮动由startAngle =(浮点)Vector.AngleBetween(x轴,VA);
浮动sweepAngle =(浮点)(Vector.AngleBetween(VA,VB)+ Vector.AngleBetween(VB,VC));
path.AddArc(
(浮点)(CX - 距离),(浮点)(CY - 距离),
(浮点)(距离* 2),(浮点)(距离* 2 ),
startAngle开始,sweepAngle);


解决方案

我会使用 DrawArc( )由ANC_Michael建议。要查找到3点经过圆弧要计算由点形成的三角形的外接圆



一旦你的外接圆计算边框与使用最小/最大尺寸DrawArc 使用圆(中心+/-半径)。现在计算你开始和使外接圆上的原点(由-circumcenter翻译)为中心的翻译点停止角度,并采取与X轴的归一化的开始和结束向量的点积:

 双startAngle开始= Math.Acos(VectorToLeftPoint.Dot(X轴)); 
双stopAngle = Math.Acos(VectorToRightPoint.Dot(X轴));



注意 DrawArc 顺时针期望的角度从X轴,所以你应该添加 Math.PI 如果计算出的向量是x轴的上方。这应该是足够的信息来调用 DrawArc()



编辑:这种方法会找到一个圆形弧不一定是'最适合'弧根据您的预计终结点行为。


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

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

What can I do?

SOLUTION:

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);

解决方案

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.

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));

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().

Edit: 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天全站免登陆