Учитывая массив точек, на их основе легко нарисовать линию, например, используя класс 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;
}