.NET GDI +:绘制线条与圆角 [英] .NET GDI+: Drawing lines with rounded corners

查看:264
本文介绍了.NET GDI +:绘制线条与圆角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于点的阵列,它很容易得出基于这些,例如,一个线使用GraphicsPath类。

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

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

...描述,类似于一个Z A线。

但在这里谈到的挑战;我需要绘制圆角如与半径10像素。通过弯道我的意思是指在没有开始或结束点线中点。在这种情况下,有两个角的(0,100)(100,0)

我曾与贝济耶,曲线和圆弧,其中一些可能持有的解决方案发挥各地 - 我只是一直没能找到它自己还没有,因为我必须要能够处理所有的角度画出线条,不只是水平或垂直线。

设置 LineJoin 对象回合是不够的,因为这与更广泛的笔只能说明


编辑::要澄清,我很清楚的GraphicsPath类的贝塞尔,曲线和圆弧的能力。我要寻找关于构建算法,可以采取任何数量的点一些更具体的建议,并与圆角把它们串起来。


解决方案

我放在一起下面的函数返回重新$ P $的路径psenting带圆角的线。该功能利用了一个LengthenLine功能,可以在这里找到

 受保护的Gr​​aphicsPath GetRoundedLine(的PointF []点,浮动cornerRadius)
{
  GraphicsPath的路径=新的GraphicsPath();
  的PointF previousEndPoint = PointF.Empty;
  的for(int i = 1; I< points.Length;我++)
  {
    的PointF的startPoint =点[我 -  1];
    的PointF终点=点[I]

    如果(ⅰ→1)
    {
      //缩短起点,并添加贝塞尔曲线为所有,但第一条线段:
      的PointF cornerPoint =的startPoint;
      LengthenLine(端点,裁判的startPoint,-cornerRadius);
      的PointF controlPoint1 = cornerPoint;
      的PointF controlPoint2 = cornerPoint;
      LengthenLine(previousEndPoint,裁判controlPoint1,-cornerRadius / 2);
      LengthenLine(的startPoint,楼盘controlPoint2,-cornerRadius / 2);
      path.AddBezier(previousEndPoint,controlPoint1,controlPoint2,的startPoint);
    }
    如果第(i + 1&其中; points.Length)//缩短除了最后线段的终点。
      LengthenLine(的startPoint,参考端点,-cornerRadius);

    path.AddLine(的startPoint,终点);
    previousEndPoint =端点;
  }
  返回路径;
}
 

解决方案

贝塞尔曲线是pretty的直接实现:

HTTP://www.$c$cproject.com/KB/食谱/ 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

Given an array of points, it is easy to draw a line based on these, e.g. using the GraphicsPath class.

For instance, the following array of points...

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

...describes a line that resembles a Z.

But here comes the challenge; I need to draw rounded corners with a radius of e.g. 10 pixels. By corners I mean the points in the line that aren't start or end points. In this case there are two corners at (0,100) and (100,0).

I've played around with beziers, curves and arcs, some of which might hold the solution - I just haven't been able to find it myself yet, since I have to be able to handle lines drawn in all angles, not just horizontal or vertical lines.

Setting the LineJoin of the Pen object to Round isn't sufficient, since this only shows with wider pens.


Edit: To clarify, I'm well aware of the bezier, curve and arc capabilities of the GraphicsPath class. I am looking for some more specific advice in regard to building the algorithm that can take any number of points, and string them together with rounded corners.


Solution

I put together the following function which returns a path representing the line with rounded corners. The function makes use of a LengthenLine function, which can be found 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;
}

解决方案

Bezier curves are pretty straightforward to implement:

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

Luckily you also have them as part of the GraphicsPath class if you wanna omit the gory details:

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

And you can also look into splines:

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

这篇关于.NET GDI +:绘制线条与圆角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆