private List <DelaunayTriangle> GenerateTriangles() { List <DelaunayTriangle> triangles = new List <DelaunayTriangle>(); Dictionary <PolyNode, Polygon> dict = new Dictionary <PolyNode, Polygon>(); PolyNode curt = m_polyTree.GetFirst(); while (curt != null) { var polygon = Convert(curt.Contour); dict.Add(curt, polygon); if (curt.IsHole && curt.Parent != null) { dict[curt.Parent].AddHole(polygon); } curt = curt.GetNext(); } foreach (var pair in dict) { var node = pair.Key; var poly = pair.Value; if (node.IsHole == false) { P2T.Triangulate(poly); triangles.AddRange(poly.Triangles); } } return(triangles); }
/// <summary> /// Triangulate polgon, create vertices /// </summary> public void Triangulate() { if (simple) { AddTriangles(inner, outer); } else { vertices = data.points; normals = data.normals; tangents = data.tangents; colors = data.colors; P2T.Triangulate(polygon); IList <DelaunayTriangle> polyTris = polygon.Triangles; triangles.Clear(); for (int i = 0; i < polyTris.Count; ++i) { triangles.Add(data.polyPoints.FindIndex(x => x.VertexCode == polyTris[i].Points[2].VertexCode)); triangles.Add(data.polyPoints.FindIndex(x => x.VertexCode == polyTris[i].Points[1].VertexCode)); triangles.Add(data.polyPoints.FindIndex(x => x.VertexCode == polyTris[i].Points[0].VertexCode)); } } }
/** * Use poly2tri library to perform a Delaunay triangulation on a given 2D contour **/ public static Triangle[] TriangulateContour(Vector2[] contour) { PolygonPoint[] pPoints = new PolygonPoint[contour.Length]; for (int i = 0; i != contour.Length; i++) { pPoints[i] = new PolygonPoint(contour[i].x, contour[i].y); } //Convert the Triangulable object to a Polygon object Polygon p = new Polygon(pPoints); //Perform the actual triangulation P2T.Triangulate(TriangulationAlgorithm.DTSweep, p); //Transform the resulting DelaunayTriangle objects into an array of Triangle objects IList <DelaunayTriangle> resultTriangles = p.Triangles; Triangle[] triangles = new Triangle[resultTriangles.Count]; for (int iTriangleIndex = 0; iTriangleIndex != resultTriangles.Count; iTriangleIndex++) { DelaunayTriangle dTriangle = resultTriangles[iTriangleIndex]; Vector3[] triangleVertices = new Vector3[3]; //invert vertices 1 and 2 for ccw order triangleVertices[0] = new Vector2((float)dTriangle.Points[0].X, (float)dTriangle.Points[0].Y); triangleVertices[1] = new Vector2((float)dTriangle.Points[2].X, (float)dTriangle.Points[2].Y); triangleVertices[2] = new Vector2((float)dTriangle.Points[1].X, (float)dTriangle.Points[1].Y); Triangle triangle = new Triangle(triangleVertices); triangles[iTriangleIndex] = triangle; } return(triangles); }
public static TriangleInfoList ConvertStringToTriangles(string text, FontStyle fontStyle, float glyphFontSize = 10f) { FontFamily fontFamily = FontFamily.GenericSansSerif; var triangles = new TriangleInfoList(); try { var textAsPolygons = GeneratePolygonsFromGlyph(fontFamily, fontStyle, text, glyphFontSize, false); var polygonSet = CreateSetFromList(textAsPolygons); P2T.Triangulate(polygonSet); foreach (var polygon in polygonSet.Polygons) { foreach (var polyTriangle in polygon.Triangles) { var triangle = new Triangle(); var triangleIndex = 0; foreach (var trianglePoint in polyTriangle.Points) { triangle.Vectors [triangleIndex].Position.X = (float)trianglePoint.X; triangle.Vectors [triangleIndex].Position.Y = (float)trianglePoint.Y; triangleIndex++; } triangles[0].Add(triangle); } } } catch (Exception exc) { Debug.WriteLine(exc); } return(triangles); }
/// <summary> /// Given a set of points ordered counter-clockwise along a contour and a set of holes, return triangle indexes. /// </summary> /// <param name="points"></param> /// <param name="holes"></param> /// <param name="indexes">Indices outside of the points list index into holes when layed out linearly. /// {vertices 0,1,2...vertices.length-1, holes 0 values, hole 1 values etc.} </param> /// <returns></returns> public static bool Triangulate(IList <Vector2> points, IList <IList <Vector2> > holes, out List <int> indexes) { indexes = new List <int>(); int index = 0; var allPoints = new List <Vector2>(points); Polygon polygon = new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++))); if (holes != null) { for (int i = 0; i < holes.Count; i++) { allPoints.AddRange(holes[i]); var holePolgyon = new Polygon(holes[i].Select(x => new PolygonPoint(x.x, x.y, index++))); polygon.AddHole(holePolgyon); } } try { P2T.Triangulate(TriangulationAlgorithm.DTSweep, polygon); } catch (System.Exception e) { Log.Info("Triangulation failed: " + e.ToString()); return(false); } foreach (DelaunayTriangle d in polygon.Triangles) { if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0) { Log.Info("Triangulation failed: Additional vertices were inserted."); return(false); } indexes.Add(d.Points[0].Index); indexes.Add(d.Points[1].Index); indexes.Add(d.Points[2].Index); } WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points); // if the re-triangulated first tri doesn't match the winding order of the original // vertices, flip 'em if (SurfaceTopology.GetWindingOrder(new Vector2[3] { allPoints[indexes[0]], allPoints[indexes[1]], allPoints[indexes[2]], }) != originalWinding) { indexes.Reverse(); } return(true); }
public TestForm() { ClientSize = new Size(1000, 1000); DoubleBuffered = true; Text = "Just a test"; Visible = true; Polygons = ExampleData.Polygons.ToList(); foreach (var poly in Polygons) { try { P2T.Triangulate(poly); } catch (Exception) { } } rotation = new Timer() { Enabled = true , Interval = 500 }; rotation.Tick += (o, e) => { i = (i + 1) % Polygons.Count; Invalidate(); }; Invalidate(); }
/*! \cond PRIVATE */ bool triangulate() { if (Outline == null || Outline.Spline == null) { Error = "Missing Outline Spline"; return(false); } if (!polyLineIsValid(Outline)) { Error = Outline.Spline.name + ": Angle must be >0"; return(false); } Vector3[] outlineVerts = Outline.getVertices(); if (outlineVerts.Length < 3) { Error = Outline.Spline.name + ": At least 3 Vertices needed!"; return(false); } p2t = new Polygon(outlineVerts); if (VertexLineOnly) { return(true); } for (int i = 0; i < Holes.Count; i++) { if (Holes[i].Spline == null) { Error = "Missing Hole Spline"; return(false); } if (!polyLineIsValid(Holes[i])) { Error = Holes[i].Spline.name + ": Angle must be >0"; return(false); } Vector3[] verts = Holes[i].getVertices(); if (verts.Length < 3) { Error = Holes[i].Spline.name + ": At least 3 Vertices needed!"; return(false); } p2t.AddHole(new Polygon(verts)); } try { P2T.Triangulate(p2t); return(true); } catch (System.Exception e) { Error = e.Message; } return(false); }
private void DrawFill(List <Vector> fillVertices) { if (m_mesh.Vertices.Count <= 2 || m_mesh.FillMode == FillMode.None || m_mesh.UvMapping.FillTexture == null) { return; } if (!m_mesh.IsClosed) { fillVertices.Add(m_mesh.FillMode != FillMode.Inverted ? m_mesh.Vertices.Last().Position : m_mesh.Vertices.First().Position); } var polygon = new Polygon(fillVertices.Select(v => new PolygonPoint(v.X, v.Y))); if (IsInverted) { var center = polygon.GetCentroid(); var size = new Size(polygon.BoundingBox.Width, polygon.BoundingBox.Height); var topLeft = new Point(center.X - size.Width, center.Y + size.Height); var topRight = new Point(center.X + size.Width, center.Y + size.Height); var bottomLeft = new Point(center.X - size.Width, center.Y - size.Height); var bottomRight = new Point(center.X + size.Width, center.Y - size.Height); var invertedPolygon = new Polygon( new PolygonPoint(bottomLeft.X, bottomLeft.Y), new PolygonPoint(topLeft.X, topLeft.Y), new PolygonPoint(topRight.X, topRight.Y), new PolygonPoint(bottomRight.X, bottomRight.Y)); invertedPolygon.AddHole(polygon); polygon = invertedPolygon; } try { P2T.Triangulate(polygon); } catch (Exception) { return; } var unitsPerFill = CalculateUnitsPerFillUv(); foreach (var triangle in polygon.Triangles) { MeshFillData.AddTriangle( new Point3D(triangle.Points._0.X, triangle.Points._0.Y, 0.0), new Point3D(triangle.Points._1.X, triangle.Points._1.Y, 0.0), new Point3D(triangle.Points._2.X, triangle.Points._2.Y, 0.0), new Point(triangle.Points._0.X / unitsPerFill.X, triangle.Points._0.Y / unitsPerFill.Y), new Point(triangle.Points._1.X / unitsPerFill.X, triangle.Points._1.Y / unitsPerFill.Y), new Point(triangle.Points._2.X / unitsPerFill.X, triangle.Points._2.Y / unitsPerFill.Y)); } }
private void GenMesh(string text, string filename, double zDepth) { Graphics g = this.CreateGraphics(); var fx = g; //var ffamilly = new FontFamily("华文楷体"); var ffamilly = new FontFamily(this.textBox1.Font.Name); FontStyle?fstyle = null; foreach (var style in new[] { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Underline, FontStyle.Strikeout }) { if (!ffamilly.IsStyleAvailable(style)) { continue; } fstyle = style; break; } if (!fstyle.HasValue) { return; } { List <List <PolygonPoint> > points_list = new List <List <PolygonPoint> >(); var polygonListofText = GeneratePolygonsFromGlyph(fx, ffamilly, fstyle.Value, text, ref points_list); //WritePointsToFile(points_list, "d:\\temp\\points_list.txt"); //WritePointsToBDMFile(points_list, "d:\\temp\\points_list.bdm"); var polygonListofBase = Copy(polygonListofText); double[] min; double[] max; GetBoundingBox(ref points_list, out min, out max); polygonListofBase.Add(new Polygon(PolygonPointsOfRect(min, max))); var polygonSetOfText = CreateSetFromList(polygonListofText); var polygonSetOfBase = CreateSetFromList(polygonListofBase); P2T.Triangulate(polygonSetOfText); P2T.Triangulate(polygonSetOfBase); List <double> triangels = new List <double>(); double z_text = zDepth; double z_base = 0; FromPolygonSetToTriangles(polygonSetOfText, z_text, triangels); FromPolygonSetToTriangles(polygonSetOfBase, z_base, triangels); GetTrianglesBetweenTwoZPlane(points_list, z_base, z_text, triangels); //reverse y for (int i = 1; i < triangels.Count; i += 3) { triangels[i] = max[1] - triangels[i]; } //WriteStl(triangels, filename); WriteStlBinary(triangels, filename); } }
public static void Triangulate(ArrayList vectors, ref Mesh mesh, bool ceiling, bool twoSided) { if (vectors.Count >= 3) { PolygonPoint[] c = new PolygonPoint[vectors.Count]; Vector3[] vectorArray = new Vector3[vectors.Count]; Vector2[] vectorArray2 = new Vector2[vectors.Count]; int[] numArray = null; if (twoSided) { numArray = new int[vectors.Count * 6]; } else { numArray = new int[vectors.Count * 3]; } for (int i = 0; i < vectors.Count; i++) { Vector2 vector = (Vector2)vectors[i]; c[i] = new PolygonPoint((double)vector.x, (double)vector.y); vectorArray[i] = new Vector3(vector.x, 0f, vector.y); vectorArray2[i] = new Vector2(vector.x, vector.y); } ArrayList list = new ArrayList(c); Polygon p = new Polygon(c); P2T.Triangulate(p); for (int j = 0; j < p.Triangles.Count; j++) { if (twoSided) { numArray[j * 6] = list.IndexOf(p.Triangles[j].Points._2); numArray[(j * 6) + 1] = list.IndexOf(p.Triangles[j].Points._1); numArray[(j * 6) + 2] = list.IndexOf(p.Triangles[j].Points._0); numArray[(j * 6) + 3] = list.IndexOf(p.Triangles[j].Points._0); numArray[(j * 6) + 4] = list.IndexOf(p.Triangles[j].Points._1); numArray[(j * 6) + 5] = list.IndexOf(p.Triangles[j].Points._2); } else if (!ceiling) { numArray[j * 3] = list.IndexOf(p.Triangles[j].Points._2); numArray[(j * 3) + 1] = list.IndexOf(p.Triangles[j].Points._1); numArray[(j * 3) + 2] = list.IndexOf(p.Triangles[j].Points._0); } else { numArray[j * 3] = list.IndexOf(p.Triangles[j].Points._0); numArray[(j * 3) + 1] = list.IndexOf(p.Triangles[j].Points._1); numArray[(j * 3) + 2] = list.IndexOf(p.Triangles[j].Points._2); } } mesh.vertices = vectorArray; mesh.triangles = numArray; mesh.uv = vectorArray2; mesh.RecalculateBounds(); } }
public static void FillPolygonTriangulation(this IDebugCanvas canvas, Polygon2 poly, FillStyle fillStyle) { var cps = new Polygon(poly.Points.Map(p => new PolygonPoint(p.X, p.Y))); P2T.Triangulate(cps); foreach (var triangle in cps.Triangles) { canvas.FillTriangle(ToDV3(triangle.Points[0]), ToDV3(triangle.Points[1]), ToDV3(triangle.Points[2]), fillStyle); } }
public TestForm() { ClientSize = new Size(1000, 1000); DoubleBuffered = true; Text = "Just a test"; Visible = true; this.KeyPreview = true; this.KeyPress += new KeyPressEventHandler(TestForm_OnKeyPress); this.KeyDown += new KeyEventHandler(TestForm_OnKeyDown); this.MouseWheel += new MouseEventHandler(TestForm_OnMouseWheel); this.MouseDown += new MouseEventHandler(TestForm_OnMouseDown); this.MouseUp += new MouseEventHandler(TestForm_OnMouseUp); this.MouseMove += new MouseEventHandler(TestForm_OnMouseMove); this.MouseDoubleClick += new MouseEventHandler(TestForm_OnMouseDoubleClick); foreach (var ps in ExampleData.PointSets) { DisplayObjects.Add(ps); } foreach (var p in ExampleData.Polygons) { DisplayObjects.Add(p); } foreach (ITriangulatable obj in DisplayObjects) { try { P2T.Triangulate(TriangulationAlgorithm.DTSweep, obj); } catch (Exception e) { Console.WriteLine(e.Message + ":\n" + e.StackTrace); } } rotation = new Timer() { Enabled = true, Interval = 500, }; rotation.Tick += (o, e) => { if (!mbPaused) { mDisplayIndex = (mDisplayIndex + 1) % DisplayObjects.Count; ResetZoomAndPan(); } }; Invalidate(); }
GameObject GenerateProvinceRegionSurface(int provinceIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation) { if (provinceIndex < 0 || provinceIndex >= provinces.Length) { return(null); } if (provinces [provinceIndex].regions == null) { ReadProvincePackedString(provinces [provinceIndex]); } if (provinces [provinceIndex].regions == null || regionIndex < 0 || regionIndex >= provinces [provinceIndex].regions.Count) { return(null); } Province province = provinces [provinceIndex]; Region region = province.regions [regionIndex]; if (region.points.Length < 3) { return(null); } // Triangulate to get the polygon vertex indices Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.points); if (_enableEnclaves && regionIndex == province.mainRegionIndex) { ProvinceSubstractProvinceEnclaves(provinceIndex, region, poly); } P2T.Triangulate(poly); // Prepare surface cache entry and deletes older surface if exists int cacheIndex = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex); string cacheIndexSTR = cacheIndex.ToString(); Transform t = surfacesLayer.transform.Find(cacheIndexSTR); if (t != null) { DestroyImmediate(t.gameObject); // Deletes potential residual surface } // Creates surface mesh GameObject surf = Drawing.CreateSurface(cacheIndexSTR, poly, material, region.rect2D, textureScale, textureOffset, textureRotation, disposalManager); surf.transform.SetParent(surfacesLayer.transform, false); surf.transform.localPosition = Misc.Vector3zero; surf.transform.localRotation = Quaternion.Euler(Misc.Vector3zero); surf.layer = gameObject.layer; surfaces [cacheIndex] = surf; return(surf); }
/// <summary> /// Cap mesh /// </summary> /// <param name="color"></param> public void Cap(Color color) { if (Vertices == null || Vertices.Length < 6) { return; } // Convert to PolygonPointExt (2D + index) // Convention: bottom vertices start at 0, top at 1 - continue every 2 vertices var points = new List <PolygonPointExt>(); for (var idx = 0; idx < Vertices.Length; idx += 2) { points.Add(new PolygonPointExt(Vertices[idx].X, Vertices[idx].Z, idx)); } var poly = new Poly2TriPolygon.Polygon(points); try { P2T.Triangulate(poly); // Get resulting faces var faces = new List <int>(Faces); foreach (var tri in poly.Triangles) { var i0 = tri.Points[0] as PolygonPointExt; var i1 = tri.Points[1] as PolygonPointExt; var i2 = tri.Points[2] as PolygonPointExt; // apply to bottom faces.Add(i2.Idx); faces.Add(i1.Idx); faces.Add(i0.Idx); // apply to top faces.Add(i2.Idx + 1); faces.Add(i1.Idx + 1); faces.Add(i0.Idx + 1); // Add roof color Colors[i0.Idx + 1] = color; Colors[i2.Idx + 1] = color; Colors[i1.Idx + 1] = color; } Faces = faces.ToArray(); Normals = ComputeNormals(Vertices, Faces); } catch (Exception ex) { // TODO Console.WriteLine(ex.Message); } }
public static TriangleInfoList ConvertStringToTrianglesWithOuterPath(string text, FontStyle fontStyle, Polygon outerPath, out PolygonSet textAsPolygonSet, float glyphFontSize = 50f) { FontFamily fontFamily = FontFamily.GenericSansSerif; textAsPolygonSet = new PolygonSet(); var triangles = new TriangleInfoList(); try { var textAsPolygons = GeneratePolygonsFromGlyph(fontFamily, fontStyle, text, glyphFontSize, true); textAsPolygonSet = CreateSetFromList(textAsPolygons); var polygonSetWithOuterPath = new PolygonSet(); foreach (var t in textAsPolygonSet.Polygons) { foreach (var hole in t.Holes) { polygonSetWithOuterPath.Add(hole); } //t.Holes.Clear(); outerPath.Holes.Add(t); } polygonSetWithOuterPath.Add(outerPath); P2T.Triangulate(polygonSetWithOuterPath); foreach (var polygon in polygonSetWithOuterPath.Polygons) { foreach (var polyTriangle in polygon.Triangles) { var triangle = new Triangle(); var triangleIndex = 0; foreach (var trianglePoint in polyTriangle.Points) { triangle.Vectors[triangleIndex].Position.X = (float)trianglePoint.X; triangle.Vectors[triangleIndex].Position.Y = (float)trianglePoint.Y; triangleIndex++; } triangles[0].Add(triangle); } } } catch (Exception exc) { Debug.WriteLine(exc); } return(triangles); }
/// <summary> /// Triangulates the point cloud. /// </summary> /// <param name="points">The point cloud.</param> /// <returns>A triangulated polygon.</returns> private static Polygon Triangulate(List <Vector2> points) { PolygonPoint[] tempPoints = new PolygonPoint[points.Count]; for (int i = 0; i < points.Count; i++) { tempPoints[i] = new PolygonPoint(points[i].X, points[i].Y); } Polygon polygon = new Polygon(tempPoints); P2T.Triangulate(polygon); return(polygon); }
/// <summary> /// Given a set of points ordered counter-clockwise along a contour, return triangle indexes. /// </summary> /// <param name="points"></param> /// <param name="indexes"></param> /// <param name="convex">Triangulation may optionally be set to convex, which will result in some a convex shape.</param> /// <returns></returns> public static bool Triangulate(IList <Vector2> points, out List <int> indexes, bool convex = false) { indexes = new List <int>(); int index = 0; Triangulatable soup = convex ? new PointSet(points.Select(x => new TriangulationPoint(x.x, x.y, index++)).ToList()) : (Triangulatable) new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++))); try { P2T.Triangulate(TriangulationAlgorithm.DTSweep, soup); } catch (System.Exception e) { Log.Info("Triangulation failed: " + e.ToString()); return(false); } foreach (DelaunayTriangle d in soup.Triangles) { if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0) { Log.Info("Triangulation failed: Additional vertices were inserted."); return(false); } indexes.Add(d.Points[0].Index); indexes.Add(d.Points[1].Index); indexes.Add(d.Points[2].Index); } WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points); // if the re-triangulated first tri doesn't match the winding order of the original // vertices, flip 'em if (SurfaceTopology.GetWindingOrder(new Vector2[3] { points[indexes[0]], points[indexes[1]], points[indexes[2]], }) != originalWinding) { indexes.Reverse(); } return(true); }
private Mesh WallFaceBuilder(WallFace wallFace) { Mesh mesh = new Mesh(); List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); var w = Utils.Round(wallFace.width); var h = wallFace.height; if (Utils.IsEqual(w, 0)) { return(mesh); } PolygonPoint[] shape = { new PolygonPoint(0, 0), new PolygonPoint(h, 0), new PolygonPoint(h, w), new PolygonPoint(0, w), }; Polygon p = new Polygon(shape); foreach (var polygonPoint in shape) { var vertex = new Vector3(0.002f, polygonPoint.Xf, polygonPoint.Yf); vertices.Add(vertex); } P2T.Triangulate(p); foreach (var triangle in p.Triangles) { var points = triangle.Points; var f1v1 = new Vector3(0.002f, points._0.Xf, points._0.Yf); var f1v2 = new Vector3(0.002f, points._1.Xf, points._1.Yf); var f1v3 = new Vector3(0.002f, points._2.Xf, points._2.Yf); triangles.Add(vertices.IndexOf(f1v1)); triangles.Add(vertices.IndexOf(f1v2)); triangles.Add(vertices.IndexOf(f1v3)); } mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); return(mesh); }
private void ConstructPolygon() { List <PolygonPoint> p2 = new List <PolygonPoint>(); int i = 0, l = _points.Count; for (; i < l; i += 1) { p2.Add(new PolygonPoint(_points[i].x, _points[i].y)); } _polygon = new Polygon(p2); P2T.Triangulate(_polygon); // _loom.QueueOnMainThread(ContinueCreatingShape); ContinueCreatingShape(); }
private void ConstructPolygon() { List <PolygonPoint> p2 = new List <PolygonPoint>(); int i = 0, l = _points.Count; for (; i < l; i += 1) { p2.Add(new PolygonPoint(_points [i].x, _points [i].y)); } _polygon = new Polygon(p2); _polygon.Simplify(); P2T.Triangulate(_polygon); ContinueCreatingShape(); }
protected void InitializeVertexData() { if (primitiveType == PrimitiveType.LineList) { List <PolygonPoint> points = GetPoints(); foreach (PolygonPoint point in points) { // It seems silly to not just say "VertexPositionColor v = new VertexPositionColor(new Vector3(vertex, 0), color);" // but its actually a JIT optimization to make sure this statement always gets inlined. // Reference: Downloaded powerpoint (Understanding XNA Framework Performance) at http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=16477 VertexPositionColor vpc = new VertexPositionColor(); vpc.Position.X = (float)point.X; vpc.Position.Y = (float)point.Y; if (vertexPositionColors.Count > 1) { vertexPositionColors.Add(lastVertexPositionColor); } lastVertexPositionColor = vpc; vertexPositionColors.Add(vpc); } } else if (primitiveType == PrimitiveType.TriangleList) { Polygon polygon = GetPolygon(); P2T.Triangulate(polygon); PolygonCount = polygon.Triangles.Count; foreach (DelaunayTriangle triangle in polygon.Triangles) { foreach (TriangulationPoint point in triangle.Points) { VertexPositionColor vpc = new VertexPositionColor(); vpc.Position.X = (float)point.X; vpc.Position.Y = (float)point.Y; vertexPositionColors.Add(vpc); } } } tranformedVPCs = vertexPositionColors.ToArray(); }
/// <summary> /// Creates a <see cref="PrimitiveType.TriangleList"/> of vertices which cover the interior of the /// specified <paramref name="points"/>. The path must be closed and describe a simple polygon. /// </summary> /// <param name="points">Points describing the border of a simple polygon.</param> /// <param name="zCoord">Z coordinate of the created vertices.</param> /// <param name="verts">Returns a <see cref="PrimitiveType.TriangleList"/> of vertices.</param> public static void Triangulate(PointF[] points, float zCoord, out PositionColoredTextured[] verts) { PointF[] pathPoints = AdjustPoints(points); if (pathPoints.Length < 3) { verts = null; return; } if (pathPoints.Length == 3) { verts = new PositionColoredTextured[3]; verts[0].Position = new Vector3(pathPoints[0].X, pathPoints[0].Y, zCoord); verts[1].Position = new Vector3(pathPoints[1].X, pathPoints[1].Y, zCoord); verts[2].Position = new Vector3(pathPoints[2].X, pathPoints[2].Y, zCoord); return; } IList <DelaunayTriangle> polygons; try { // Triangulation can fail (i.e. polygon is self-intersecting) var poly = new Poly2Tri.Polygon(pathPoints.Select(p => new PolygonPoint(p.X, p.Y))); P2T.Triangulate(poly); polygons = poly.Triangles; } catch (Exception) { verts = null; return; } verts = new PositionColoredTextured[polygons.Count * 3]; int offset = 0; foreach (DelaunayTriangle triangle in polygons) { verts[offset++].Position = new Vector3((float)triangle.Points[0].X, (float)triangle.Points[0].Y, zCoord); verts[offset++].Position = new Vector3((float)triangle.Points[1].X, (float)triangle.Points[1].Y, zCoord); verts[offset++].Position = new Vector3((float)triangle.Points[2].X, (float)triangle.Points[2].Y, zCoord); } }
GameObject GenerateCountryRegionSurface(int countryIndex, int regionIndex, Material material, Vector2 textureScale, Vector2 textureOffset, float textureRotation) { if (countryIndex < 0 || countryIndex >= _countries.Length) { return(null); } Country country = _countries [countryIndex]; Region region = country.regions [regionIndex]; if (region.points.Length < 3) { return(null); } Poly2Tri.Polygon poly = new Poly2Tri.Polygon(region.points); // Extracts enclaves from main region if (_enableEnclaves && regionIndex == country.mainRegionIndex) { // Remove negative provinces if (_showProvinces) { CountrySubstractProvinceEnclaves(countryIndex, region, poly); } else { CountrySubstractCountryEnclaves(countryIndex, region, poly); } } P2T.Triangulate(poly); // Prepare surface cache entry and deletes older surface if exists int cacheIndex = GetCacheIndexForCountryRegion(countryIndex, regionIndex); string id = cacheIndex.ToString(); // Creates surface mesh GameObject surf = Drawing.CreateSurface(id, poly, material, region.rect2D, textureScale, textureOffset, textureRotation, disposalManager); ParentObjectToRegion(id, COUNTRY_SURFACES_ROOT_NAME, surf); surfaces [cacheIndex] = surf; return(surf); }
private VertexPositionTexture[] createVerticesFromPoints(List <Vector2> points, out int primitiveCount) { List <PolygonPoint> p2tPoints = new List <PolygonPoint>(); Polygon polygon; Vector2 topLeft = points[0]; Vector2 bottomRight = points[0]; VertexPositionTexture[] vertices; int index = 0; foreach (Vector2 v in points) { p2tPoints.Add(new PolygonPoint(v.X, v.Y)); topLeft = Vector2.Min(v, topLeft); bottomRight = Vector2.Max(v, bottomRight); } polygon = new Polygon(p2tPoints); P2T.Triangulate(polygon); primitiveCount = polygon.Triangles.Count; vertices = new VertexPositionTexture[primitiveCount * 3]; foreach (DelaunayTriangle triangle in polygon.Triangles) { Vector2 p1 = new Vector2(triangle.Points[0].Xf, triangle.Points[0].Yf); Vector2 p2 = new Vector2(triangle.Points[1].Xf, triangle.Points[1].Yf); Vector2 p3 = new Vector2(triangle.Points[2].Xf, triangle.Points[2].Yf); vertices[index++] = new VertexPositionTexture( new Vector3(p1, 0), (p1 - topLeft) / (bottomRight - topLeft)); vertices[index++] = new VertexPositionTexture( new Vector3(p2, 0), (p2 - topLeft) / (bottomRight - topLeft)); vertices[index++] = new VertexPositionTexture( new Vector3(p3, 0), (p3 - topLeft) / (bottomRight - topLeft)); } return(vertices); }
// Token: 0x060042B5 RID: 17077 RVA: 0x001556A8 File Offset: 0x00153AA8 public List <int> Triangulate() { List <PolygonPoint> list = new List <PolygonPoint>(this.Points.Length); foreach (Vector2 vector in this.Points) { list.Add(new PolygonPoint((double)vector.x, (double)vector.y)); } ThirdParty.P2T.Polygon polygon = new ThirdParty.P2T.Polygon(list); foreach (Polygon polygon2 in this.holes) { List <PolygonPoint> list2 = new List <PolygonPoint>(polygon2.Points.Length); foreach (Vector2 vector2 in polygon2.Points) { list2.Add(new PolygonPoint((double)vector2.x, (double)vector2.y)); } polygon.AddHole(new ThirdParty.P2T.Polygon(list2)); } P2T.Triangulate(polygon); int count = polygon.Triangles.Count; List <int> list3 = new List <int>(count * 3); this.Points = new Vector2[count * 3]; int num = 0; for (int k = 0; k < count; k++) { list3.Add(num); list3.Add(num + 1); list3.Add(num + 2); this.Points[num + 2].x = (float)polygon.Triangles[k].Points._0.X; this.Points[num + 2].y = (float)polygon.Triangles[k].Points._0.Y; this.Points[num + 1].x = (float)polygon.Triangles[k].Points._1.X; this.Points[num + 1].y = (float)polygon.Triangles[k].Points._1.Y; this.Points[num].x = (float)polygon.Triangles[k].Points._2.X; this.Points[num].y = (float)polygon.Triangles[k].Points._2.Y; num += 3; } return(list3); }
/// <summary> /// 使用Poly2Tri进行三角剖分 /// </summary> /// <param name="polygons"></param> /// <returns></returns> private static List <DelaunayTriangle> GenerateTriangles(List <List <IntPoint> > polygons) { //根据时针方向判断可走区域和障碍 var walkables = new List <Polygon>(); var blockeds = new List <Polygon>(); for (int i = 0; i < polygons.Count; i++) { var list = Convert(polygons[i]); if (IsCCW(polygons[i])) { walkables.Add(new Polygon(list)); } else { blockeds.Add(new Polygon(list)); } } //可以考虑添加SteinerPoint来避免生成狭长的三角形 //三角剖分 List <DelaunayTriangle> triangles = new List <DelaunayTriangle>(); for (int index = 0; index < walkables.Count; index++) { for (int i = 0; i < blockeds.Count; i++) { walkables[index].AddHole(blockeds[i]); } P2T.Triangulate(walkables[index]); triangles.AddRange(walkables[index].Triangles); } return(triangles); }
public static Mesh triangulate(Spline s, AXTexCoords tex) { Debug.Log("E"); if (s == null) { return(null); } // poly has verts that are delimeted by 8888888 for holes // 1. transpose points to poly2tri structures // 2. create mesh Polygon _polygon = null; List <PolygonPoint> _points = new List <PolygonPoint>(); for (int i = 0; i < s.controlVertices.Count; i++) { _points.Add(new PolygonPoint((double)s.controlVertices[i].x, (double)s.controlVertices[i].y)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } // populate the polygon triangles if (_polygon != null) { P2T.Triangulate(_polygon); return(polygon2mesh(_polygon, tex)); } return(null); }
public override IStyleData Calculate(MarkupFiller filler, MarkupLOD lod) { var contour = filler.IsMedian ? SetMedianOffset(filler) : filler.Contour.Trajectories.ToArray(); if (NeedReverse(contour)) { contour = contour.Select(t => t.Invert()).Reverse().ToArray(); } var parts = contour.Select(t => StyleHelper.CalculateSolid(t, lod, (tr) => tr, MinAngle, MinLength, MaxLength)).ToArray(); for (var i = 0; i < parts.Length; i += 1) { var partI = parts[i]; var partJ = parts[(i + 1) % parts.Length]; if (!FindIntersects(partI, partJ, false)) { FindIntersects(partJ, partI, true); } } var points = parts.SelectMany(p => p).Select(t => t.StartPosition).ToArray(); if (points.Length < 3) { return(null); } var polygon = new Polygon(points.Select(p => new PolygonPoint(p.x, p.z))); P2T.Triangulate(polygon); var triangles = polygon.Triangles.SelectMany(t => t.Points.Select(p => polygon.IndexOf(p))).ToArray(); return(new MarkupStylePolygonMesh(filler.Markup.Height, Elevation, parts.Select(g => g.Count).ToArray(), points, triangles, MaterialType)); }
public void triangulate() { List <PolygonPoint> points = new List <PolygonPoint>(); PointListNode current = _headPoint; _polygonPosition = current.position; while (current != null) { _polygonPosition = Vector2.Min(current.position, _polygonPosition); points.Add(new PolygonPoint(current.position.X, current.position.Y)); current = current.next; } Polygon polygon = new Polygon(points); P2T.Triangulate(polygon); _primitiveCount = polygon.Triangles.Count; int index = 0; foreach (DelaunayTriangle triangle in polygon.Triangles) { for (int i = 0; i < 3; i++) { _vertices[index++] = new VertexPositionColorTexture( new Vector3(triangle.Points[i].Xf, triangle.Points[i].Yf, 0), Color.White, Vector2.Zero); } } if (_polygonTexture != null) { _polygonTexture.Dispose(); } _polygonTexture = _level.controller.view.renderPolygon(_vertices, _primitiveCount); }
public static List <List <OxyPlot.DataPoint> > TriangulatePolygon(List <OxyPlot.DataPoint> xyPoints) { int nVertices = xyPoints.Count; if (nVertices <= 0) { return(new List <List <OxyPlot.DataPoint> >()); } var points = new List <PolygonPoint>(); foreach (var xy in xyPoints) { points.Add(new PolygonPoint(xy.X, xy.Y)); } Polygon poly = new Polygon(points); P2T.Triangulate(poly); List <List <OxyPlot.DataPoint> > simpleShapes = new List <List <OxyPlot.DataPoint> >(); foreach (var triangle in poly.Triangles) { List <OxyPlot.DataPoint> simple = new System.Collections.Generic.List <OxyPlot.DataPoint>(); foreach (var pt in triangle.Points) { simple.Add(new OxyPlot.DataPoint(pt.X, pt.Y)); } simpleShapes.Add(simple); } return(simpleShapes); }