Frage

ein Array von Punkten gegeben, ist es einfach, eine Linie auf dieser Basis zu zeichnen, z.B. Verwendung der Graphic Klasse.

Zum Beispiel kann die folgende Anordnung von Punkten ...

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

... beschreibt eine Linie, die einen Z ähnelt.

Aber hier kommt die Herausforderung; Ich muß abgerundete Ecken mit einem Radius von beispielsweise zeichnen 10 Pixel. Durch Ecken meine ich die Punkte in der Zeile, die nicht gestartet werden oder Endpunkte. In diesem Fall gibt es zwei Ecken an (0,100) und (100,0).

Ich habe gespielt um mit beziers, Kurven und Bögen, die Lösung von denen einige halten könnte - ich habe nur nicht in der Lage, es selbst noch zu finden, da ich Linien in allen Winkeln gezogen zu können, haben zu handhaben, nicht nur horizontale oder vertikale Linien.

Zur Einstellung der LineJoin des Pen Objekts Round ist nicht ausreichend, da dies nur zeigt mit breiteren Stiften.


Edit: Um zu klären, ich bin sehr wohl bewusst der Bezier-Kurve und Bogen Fähigkeiten der Graphic Klasse. Ich suche nach etwas mehr spezifische Beratung in Bezug um den Algorithmus zu bauen, die eine beliebige Anzahl von Punkten nehmen, und reihen sie zusammen mit abgerundeten Ecken.


Lösung

I zusammen die folgende Funktion, die einen Weg der Leitung mit abgerundeten Ecken darstellt, zurückgibt. Die Funktion nutzt eine LengthenLine Funktion, die finden Sie hier .

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;
}
War es hilfreich?

Lösung

Bezier-Kurven sind ziemlich einfach zu implementieren:

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

Zum Glück haben Sie sie auch als Teil der Klasse Graphic, wenn Sie wollen die blutigen Details auslassen:

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

Und Sie können auch in Splines aussehen:

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

Andere Tipps

Dies ist die Funktion, die ich verwende, um ein Rechteck mit abgerundeten Ecken zu ziehen ... von dem aus Sie den Winkel jeder Zeile berechnen können.

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

Hope diese Sie hilft, in dem schwierigeren Teil der Trigonometrie;)

Diese URL hat eine Beschreibung, wie abgerundete Rechtecke zu zeichnen, die dir helfen könnten beginnen.

Aber ich würde denken, dass, wenn sonst nichts Sie wäre in der Lage mehr Punkte auf Ihren Weg zu addieren, um die Illusion von abgerundeten Ecken zu geben. So fügen Sie in mehreren Punkten zwischen 0,0 und 100,0. Ein Beispiel könnte sein:

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

ich diesen Weg nicht in irgendeiner Weise getestet haben, zog nur ein paar Zahlen, die aus der Luft funktionieren könnte:)

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top