给定一个点阵列,基于这些点很容易画一条线,例如使用GraphicsPath类。

例如,以下点数组...

[0]: (0,0)
[1]: (100,0)
[2]: (0,100)
[3]: (100,100)

...描述类似于Z的线。

但是挑战来了;我需要绘制半径为例如的圆角10个像素。拐角是指直线中不是起点或终点的点。在这种情况下,(0,100)(100,0)有两个角落。

我玩过贝塞尔曲线,曲线和弧线,其中一些可能会找到解决方案-我只是自己还找不到,因为我必须能够处理所有角度绘制的线,而不仅仅是水平线或垂直线。

LineJoin对象的Pen设置为Round是不够的,因为这只能用较宽的笔显示。

编辑:为了明确起见,我非常了解GraphicsPath类的bezier,曲线和圆弧功能。我正在寻找有关构建算法的更具体建议,该算法可以采用任意数量的点,并将其与圆角连接在一起。



我将以下函数放在一起,该函数返回一个路径,该路径表示带有圆角的线。该函数利用LengthenLine函数,可以在here中找到它。
protected GraphicsPath GetRoundedLine(PointF[] points, float cornerRadius)
{
  GraphicsPath path = new GraphicsPath();
  PointF previousEndPoint = PointF.Empty;
  for (int i = 1; i < points.Length; i++)
  {
    PointF startPoint = points[i - 1];
    PointF endPoint = points[i];

    if (i > 1)
    {
      // shorten start point and add bezier curve for all but the first line segment:
      PointF cornerPoint = startPoint;
      LengthenLine(endPoint, ref startPoint, -cornerRadius);
      PointF controlPoint1 = cornerPoint;
      PointF controlPoint2 = cornerPoint;
      LengthenLine(previousEndPoint, ref controlPoint1, -cornerRadius / 2);
      LengthenLine(startPoint, ref controlPoint2, -cornerRadius / 2);
      path.AddBezier(previousEndPoint, controlPoint1, controlPoint2, startPoint);
    }
    if (i + 1 < points.Length) // shorten end point of all but the last line segment.
      LengthenLine(startPoint, ref endPoint, -cornerRadius);

    path.AddLine(startPoint, endPoint);
    previousEndPoint = endPoint;
  }
  return path;
}

最佳答案

贝塞尔曲线非常容易实现:

http://www.codeproject.com/KB/recipes/BezirCurves.aspx

幸运的是,如果您想省略血腥的细节,也可以将它们作为GraphicsPath类的一部分:

http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.graphicspath.addbezier.aspx

您还可以查看样条曲线:

http://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.graphicspath.addcurve.aspx

10-08 15:18