【问题标题】:C# Drawing Arc with 3 PointsC# 用 3 个点绘制圆弧
【发布时间】:2010-05-24 15:28:22
【问题描述】:

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

我尝试了 .DrawCurve 和 .DrawBezier,但结果并不完全是弧线。

我能做什么?

解决方案:

经过几个小时的代码编写,我设法用这个算法画出了我想要的东西(给出 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);

【问题讨论】:

  • 您是指圆弧,还是任何弧都可以?
  • 循环,我忘了补充

标签: c# graphics drawing


【解决方案1】:

我会按照 ANC_Michael 的建议使用 DrawArc()。要找到通过 3 个点的弧,您需要计算这些点形成的三角形的 circumcircle

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

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

请注意,DrawArc 预计从 X 轴顺时针方向的角度,因此如果计算出的向量在 X 轴上方,则应添加 Math.PI。这些信息应该足以致电DrawArc()

编辑:此方法会根据您预期的端点行为找到一个圆形弧,而不一定是“最佳拟合”弧。

【讨论】:

    【解决方案2】:

    您是否尝试过 DrawArc 方法并查看您是否可以以某种方式操纵您的 3 点?

    也许

    Pen blackPen= new Pen(Color.Black, 3);
    // Create rectangle to bound ellipse.
    Rectangle rect = new Rectangle(initial x, initial y, final x, median y);
    // Create start and sweep angles on ellipse.
    float startAngle =  0F;
    float sweepAngle = 270.0F;
    // Draw arc to screen.
    e.Graphics.DrawArc(blackPen, rect, startAngle, sweepAngle);
    

    http://msdn.microsoft.com/en-us/library/system.drawing.graphics.drawarc%28VS.71%29.aspx

    【讨论】:

    • 我没有角度,我不知道如何计算它们,点可以在任何地方(它们是从 Oracle 内部 FDO 中的 AutoMap 3D 导出​​的)
    猜你喜欢
    • 1970-01-01
    • 2011-05-10
    • 2016-01-20
    • 2018-03-27
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多