3

点の配列が与えられると、たとえば 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;
}
4

3 に答える 3

6

これは、角の丸い長方形を描くために使用する関数です...これから、各線の角度を計算できます。

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

これが三角法の難しい部分で役立つことを願っています;)

于 2009-11-26T21:27:08.530 に答える
3

ベジエ曲線の実装は非常に簡単です。

http://www.codeproject.com/KB/recipes/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

于 2009-11-26T21:35:59.997 に答える
0

このURL には、最初に役立つ角丸長方形の描画方法が説明されています。

しかし、他に何もなければ、パスにポイントを追加して、角が丸いという錯覚を与えることができると思います。したがって、0,0 から 100,0 の間のいくつかのポイントを追加します。例は次のとおりです。

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

私はそのパスをまったくテストしていません。空中でうまくいくかもしれないいくつかの数字を引っ張っただけです:)。

于 2009-11-26T21:21:01.863 に答える