代码之家  ›  专栏  ›  技术社区  ›  bernhof

.NET GDI+:使用圆角绘制线

  •  3
  • bernhof  · 技术社区  · 16 年前

    给定一组点,可以很容易地基于这些点绘制一条线,例如使用GraphicsPath类。

    例如,下面的点数组。。。

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

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

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

    设定 LineJoin Pen Round 这是不够的,因为这只显示更宽的笔。


    为了澄清,我非常了解GraphicsPath类的bezier、曲线和圆弧功能。我正在寻找一些关于构建算法的更具体的建议,该算法可以获取任意数量的点,并用圆角将它们串在一起。


    解决方案

    我将下面的函数放在一起,它返回一条表示带圆角的线的路径。该函数使用一个lengthline函数,可以找到 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;
    }
    
    3 回复  |  直到 9 年前
        1
  •  6
  •   Romias    16 年前

    这是我用来画圆角矩形的函数。。。 由此可以计算每条线的角度。

    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
    

    希望这能帮助你学习更难的三角学;)

        3
  •  0
  •   Glenn    16 年前

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

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

    我没有以任何方式测试这条路径,只是从空中提取了一些可能可行的数字:)。