3 votes

.NET GDI+ : Dessiner des lignes avec des coins arrondis

Étant donné un tableau de points, il est facile de tracer une ligne à partir de ceux-ci, par exemple en utilisant la classe GraphicsPath.

Par exemple, le tableau suivant de points...

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

...décrit une ligne qui ressemble à un Z.

Mais voici le défi : je dois dessiner des coins arrondis avec un rayon de 10 pixels, par exemple. Par coins, j'entends les points de la ligne qui ne sont pas des points de départ ou d'arrivée. Dans ce cas, il y a deux coins à (0,100) y (100,0) .

J'ai joué avec des béziers, des courbes et des arcs, dont certains pourraient contenir la solution - je n'ai simplement pas encore pu la trouver moi-même, car je dois être capable de gérer des lignes dessinées dans tous les angles, et pas seulement des lignes horizontales ou verticales.

Fixer le LineJoin de la Pen à l'objet Round n'est pas suffisant, car cela ne se voit qu'avec des stylos plus larges.


Edit : Pour clarifier, je suis bien conscient des capacités de bézier, de courbe et d'arc de la classe GraphicsPath. Je suis à la recherche de conseils plus spécifiques concernant la construction de l'algorithme qui peut prendre n'importe quel nombre de points et les enchaîner avec des coins arrondis.


Solution

J'ai mis au point la fonction suivante qui renvoie un chemin représentant la ligne avec des coins arrondis. La fonction utilise la fonction LengthenLine, que l'on trouve à l'adresse suivante aquí .

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;
}

6voto

Romias Points 5668

Voici la fonction que j'utilise pour dessiner un rectangle avec des coins arrondis... à partir de cela vous pouvez calculer l'angle de chaque ligne.

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

J'espère que cela vous aidera dans la partie la plus difficile de la trigonométrie ;)

3voto

Pedery Points 2716

Les courbes de Bézier sont assez simples à mettre en œuvre :

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

Heureusement, ils font également partie de la classe GraphicsPath si vous voulez éviter les détails sanglants :

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

Et vous pouvez également vous pencher sur les splines :

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

0voto

Glenn Points 888

Ce site url a une description de la façon de dessiner des rectangles arrondis qui pourrait vous aider à démarrer.

Mais je pense qu'à défaut d'autre chose, vous pourriez ajouter plus de points à votre trajectoire, pour donner l'illusion de coins arrondis. Ajoutez donc plusieurs points entre 0,0 et 100,0. Un exemple pourrait être :

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

Je n'ai pas testé cette voie de quelque manière que ce soit, j'ai juste sorti des chiffres qui pourraient fonctionner :).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X