点の配列が与えられると、たとえば GraphicsPath クラスを使用して、これらに基づいて簡単に線を描くことができます。
たとえば、次の点の配列...
[0]: (0,0)
[1]: (100,0)
[2]: (0,100)
[3]: (100,100)
...Z に似た線を表します。
しかし、ここで課題が発生します。たとえば、半径 10 ピクセルの丸い角を描く必要があります。コーナーとは、始点でも終点でもない線の点を意味します。この場合、 と に 2 つのコーナーが(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;
}