给定一个点数组,很容易根据这些点画一条线,例如使用 GraphicsPath 类。
例如,以下点数组...
[0]: (0,0)
[1]: (100,0)
[2]: (0,100)
[3]: (100,100)
...描述一条类似于 Z 的线。
但挑战来了;我需要绘制半径为 10 像素的圆角。我所说的角是指线中不是起点或终点的点。(0,100)
在这种情况下,在和处有两个角(100,0)
。
我玩过贝塞尔曲线、曲线和弧线,其中一些可能是解决方案 - 我自己还没有找到它,因为我必须能够处理以所有角度绘制的线,而不仅仅是水平线或垂直线。
将对象的 设置为LineJoin
是不够的,因为这只显示更宽的笔。Pen
Round
编辑:澄清一下,我很清楚 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;
}