3

给定一个点数组,很容易根据这些点画一条线,例如使用 GraphicsPath 类。

例如,以下点数组...

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

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

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

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

将对象的 设置为LineJoin是不够的,因为这只显示更宽的笔。PenRound


编辑:澄清一下,我很清楚 GraphicsPath 类的贝塞尔曲线、曲线和圆弧功能。我正在寻找一些关于构建可以获取任意数量点的算法的更具体的建议,并将它们与圆角串在一起。


解决方案

我把下面的函数放在一起,它返回一个代表圆角线的路径。该函数使用 LengthenLine 函数,可以在此处找到。

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;
}
4

3 回答 3

6

这是我用来绘制圆角矩形的函数......从这里你可以计算每条线的角度。

Public Sub DrawRoundRect(ByVal g As Graphics, ByVal p As Pen, ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single, ByVal radius As Single)
    Dim gp As GraphicsPath = New GraphicsPath
    gp.AddLine(x + radius, y, x + width - (radius * 2), y)
    gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90)
    gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2))
    gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90)
    gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height)
    gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90)
    gp.AddLine(x, y + height - (radius * 2), x, y + radius)
    gp.AddArc(x, y, radius * 2, radius * 2, 180, 90)
    gp.CloseFigure()
    g.DrawPath(p, gp)
    gp.Dispose()
End Sub

希望这可以帮助您解决三角学的困难部分;)

于 2009-11-26T21:27:08.530 回答
3

贝塞尔曲线很容易实现:

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

于 2009-11-26T21:35:59.997 回答
0

这个url 描述了如何绘制圆角矩形,这可能会帮助你开始。

但我认为,如果不出意外,您将能够为您的路径添加更多点,以产生圆角的错觉。因此,在 0,0 和 100,0 之间添加几个点。一个例子可能是:

(0,0) (90,0) (95,5) (95,10) (0,100)

我没有以任何方式测试过那条路径,只是提取了一些可能会凭空出现的数字:)。

于 2009-11-26T21:21:01.863 回答