Triangulación de un polígono simple

Triangulando un polígono

Los desarrolladores pueden elegir vértices de un área de polígono, y luego formar triángulos llamando al método Triangulate de la clase PolygonModifier, cada uno de los formularios V{1}, V{i-1}, V{i} con el índice i yendo de 3 a n. Las clases Vertex y PolygonCanvas en el archivo Triangulate/PolygonCanvas.cs bajo la aplicación de demostración (nombre: Triangulate) demuestra la forma de triangular un polígono usando Aspose.3D API.

Muestra de programación para triangulación

En este ejemplo de código se seleccionan vértices de un área de polígono y, a continuación, se aplica un algoritmo para crear triángulos. Puede descargar el proyecto de trabajo completo de este ejemplo desde Aquí.

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