Triangulation d'un polygone simple
Contents
[
Hide
]
En utilisant Aspose.3D for .NET API, les développeurs peuvent trianguler un polygone simple. Tout polygone peut être divisé en triangles. Toutes les opérations et les calculs pour les triangles peuvent être appliqués par morceaux au polygone.
Triangulation d’un polygone
Les développeurs peuvent choisir des sommets dans une zone de polygone, puis former des triangles en appelant la méthode Triangulate de la classe PolygonModifier, chacune de la forme V{1}, V{i-1}, V{i} avec l’index i allant de 3 à n. Les classes Vertex et PolygonCanvas du fichier Triangulate/PolygonCanvas.cs sous l’application de démonstration (nom: Triangulate) montrent comment trianguler un polygone en utilisant Aspose.3D API.
Nous avons préparé un projet démo. Veuillez vous référer à Cette URL.
Échantillon de programmation pour la triangulation
Cet exemple de code sélectionne les sommets d’une zone de polygone, puis applique un algorithme pour créer des triangles. Vous pouvez télécharger le projet de travail complet de cet exemple à partir de Ici.
// For complete examples and data files, please go to https://github.com/aspose-3d/Aspose.3D-for-.NET
public class Vertex
{
[Browsable(false)]
public int Index { get; set; }
public double X { get; set; }
public double Y { get; set; }
public Vertex(int index, double x, double y)
{
Index = index;
X = x;
Y = y;
}
public override string ToString()
{
return string.Format("#{0}: {1} {2}", Index, X, Y);
}
}
class PolygonCanvas : Control
{
public List<Vertex> points = new List<Vertex>();
public event EventHandler TriangleUpdated;
private Point mousePos;
private Pen virtualLine = new Pen(Color.DarkSeaGreen);
private Vector4[][] triangles;
private int[][] triangleIndices;
private Pen polygonPen = Pens.Black;
private Brush[] brushes = new Brush[] {Brushes.Blue, Brushes.BlueViolet, Brushes.DarkCyan, Brushes.ForestGreen, Brushes.LimeGreen};
private Brush textBrush = Brushes.Black;
public PolygonCanvas()
{
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.Selectable, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint , true);
Cursor = Cursors.Cross;
virtualLine.DashStyle = DashStyle.Dash;
virtualLine.DashPattern = new float[] {10, 10};
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.Clear(Color.AliceBlue);
if (points.Count == 0)
return;
Size size = this.Size;
if (points.Count == 1)
{
// Draw virtual line
PointF pt = ToPoint(points[0], size);
g.DrawLine(virtualLine, mousePos, pt);
}
else if (points.Count == 2)
{
// Draw virtual triangle
PointF pt1 = ToPoint(points[0], size);
PointF pt2 = ToPoint(points[1], size);
g.DrawLine(polygonPen, pt2, pt1);
g.DrawLine(virtualLine, mousePos, pt1);
g.DrawLine(virtualLine, mousePos, pt2);
}
else
{
// Draw polygon and virtual line
// Draw triangles
if (triangles != null)
{
for (int i = 0; i < triangles.Length; i++)
{
PointF[] tri = ToPoints(triangles[i]);
// Shrink the triangle so we can see each triangle
float inv = 1.0f/3.0f;
float cx= (tri[0].X + tri[1].X + tri[2].X) * inv;
float cy= (tri[0].Y + tri[1].Y + tri[2].Y) * inv;
Shrink(tri, 0, cx, cy);
Shrink(tri, 1, cx, cy);
Shrink(tri, 2, cx, cy);
Brush brush = brushes[i%brushes.Length];
g.FillPolygon(brush, tri);
// Draw triangle index
string text = string.Format("{0}/{1}/{2}", triangleIndices[i][0], triangleIndices[i][1], triangleIndices[i][2]);
g.DrawString(text, Font, textBrush, cx, cy);
}
}
// Draw index of each vertex
PointF[] polygon = ToPoints(this.points);
g.DrawPolygon(polygonPen, polygon);
for (int i = 0; i < polygon.Length; i++)
{
string text = string.Format("{0}", i);
g.DrawString(text, Font, textBrush, polygon[i]);
}
g.DrawLine(virtualLine, mousePos, polygon[0]);
g.DrawLine(virtualLine, mousePos, polygon[polygon.Length - 1]);
}
}
private void Shrink(PointF[] tri, int i, float cx, float cy)
{
float dx = tri[i].X - cx;
float dy = tri[i].Y - cy;
float inv = 5.0f/(float) Math.Sqrt(dx*dx + dy*dy);
dx *= inv;
dy *= inv;
tri[i] = new PointF(tri[i].X - dx, tri[i].Y - dy);
}
private PointF[] ToPoints(IList<Vector4> vec)
{
Size size = Size;
PointF[] ret = new PointF[vec.Count];
for(int i = 0; i < ret.Length; i++)
ret[i] = new PointF((float)vec[i].x * size.Width, (float)vec[i].y * Height);
return ret;
}
private PointF[] ToPoints(IList<Vertex> vec)
{
Size size = Size;
PointF[] ret = new PointF[vec.Count];
for(int i = 0; i < ret.Length; i++)
ret[i] = ToPoint(vec[i], size);
return ret;
}
private PointF ToPoint(Vertex vec, Size size)
{
return new PointF((float)vec.X * size.Width, (float)vec.Y * Height);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
mousePos = e.Location;
Invalidate();
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
Vertex pt = new Vertex(points.Count, e.X*1.0/Width, e.Y*1.0/Height);
points.Add(pt);
UpdateTriangles();
}
else
{
// Erase last point
if (points.Count > 0)
{
points.RemoveAt(points.Count - 1);
UpdateTriangles();
}
}
}
public void UpdateTriangles()
{
DoTriangulate();
Invalidate();
if(TriangleUpdated != null)
TriangleUpdated(this, new EventArgs());
}
/// <summary>
/// Triangulate the polygon into a lot of triangles
/// </summary>
private void DoTriangulate()
{
triangles = null;
if (points.Count <= 3)
return;
// Convert to Vector4[]
Vector4[] controlPoints = new Vector4[points.Count];
for (int i = 0; i < points.Count; i++)
{
controlPoints[i] = new Vector4(points[i].X, points[i].Y, 0);
}
// Triangulate the polygon
triangleIndices = PolygonModifier.Triangulate(controlPoints);
// Save triangle vertex for later drawing.
triangles = new Vector4[triangleIndices.Length][];
for (int i = 0; i < triangleIndices.Length; i++)
{
int[] triangleFace = triangleIndices[i];
Vector4[] triangle = triangles[i] = new Vector4[3];
triangle[0] = controlPoints[triangleFace[0]];
triangle[1] = controlPoints[triangleFace[1]];
triangle[2] = controlPoints[triangleFace[2]];
}
}
}