Triangolazione di un poligono semplice
Contents
[
Hide
]
Utilizzando Aspose.3D for .NET API, gli sviluppatori possono triangolare un semplice poligono. Qualsiasi poligono può essere diviso in triangoli. Tutte le operazioni e i calcoli per i triangoli possono essere applicati a tratti al poligono.
Triangolazione di un poligono
Gli sviluppatori potrebbero scegliere i vertici da un’area poligonale, quindi formare triangoli chiamando il metodo Triangulate
della classe PolygonModifier
, ciascuno dei formati V{1}, V{i-1}, V{i} con l’indice i che va da 3 a n. Le classi Vertex
e PolygonCanvas
nel file Triangulate/PolygonCanvas.cs
sotto l’applicazione demo (nome: Triangulate) dimostrano il modo di triangolare un poligono usando Aspose.3D API.
Abbiamo preparato un progetto demo. Fai riferimento a Questo URL.
Campione di programmazione per la triangolazione
Questo esempio di codice seleziona i vertici da un’area poligonale e quindi applica un algoritmo per creare triangoli. Puoi scaricare il progetto di lavoro completo di questo esempio da Qui.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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]]; | |
} | |
} | |
} |