/** * Creates a TriangleNet IMesh from a list of shapes. The first shape is considered the base * and the rest as hole in that base. */ public static IMesh makeMesh(this List <Shape> shapes) { var polygon = new TriangleNet.Geometry.Polygon(); // Add shapes for (int i = 0; i < shapes.Count; i++) { var points = shapes[i].points; if (points.Count < 3) { return(null); } var isHole = i > 0; polygon.Add(new Contour(points.ToListVertex()), isHole); } var quality = new QualityOptions() { MinimumAngle = 25 }; // return polygon.Triangulate(); return(polygon.Triangulate(quality)); }
public static Mesh MeshFromVoronoi(Voronoi voronoi) { var options = new TriangleNet.Meshing.ConstraintOptions { ConformingDelaunay = true }; var vertices = new List <Vector3>(); var verticesIndex = 0; var triangles = new List <int>(); var colors = new List <Color>(); var regions = voronoi.Regions(); for (var i = 0; i < regions.Count; i++) { var region = regions[i]; var polygon = new TriangleNetGeo.Polygon(); foreach (var corner in region) { polygon.Add(new TriangleNetGeo.Vertex(corner.x, corner.y)); } var cellMesh = (TriangleNet.Mesh)polygon.Triangulate(options); vertices.AddRange( cellMesh.Vertices.Select(v => new Vector3((float)v.x, 0, (float)v.y)) ); triangles.AddRange( cellMesh.Triangles.SelectMany( t => t.vertices.Select(v => v.id + verticesIndex) .Reverse() // Reverse triangles so they're facing the right way ) ); // Update index so the next batch of triangles point to the correct vertices verticesIndex = vertices.Count; // Assign same color to all vertices in region var regionColor = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f)); colors.AddRange(cellMesh.Vertices.Select(v => regionColor)); } // Just make world-space UVs for now var uvs = vertices.Select(v => new Vector2(v.x, v.y)); var mesh = new Mesh { vertices = vertices.ToArray(), colors = colors.ToArray(), uv = uvs.ToArray(), triangles = triangles.ToArray() }; mesh.RecalculateNormals(); return(mesh); }
internal void CalcDL(Structure str) { if (str == null || str.RedPlanning == null || str.RedPlanning.Count == 0) { return; } List <Vertex> vrtxs = new List <Vertex>(); Vertex vrtx; int i = 1; foreach (PlanningVertex item in str.RedPlanning) { vrtx = new Vertex(item.X, item.Y, item.Number, 2); vrtx.Attributes[0] = item.Red; vrtx.Attributes[1] = item.Black; vrtxs.Add(vrtx); i++; } Contour cnt = new Contour(vrtxs); TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon(); polygon.Add(cnt); GenericMesher mesher = new GenericMesher(); ConstraintOptions constraint = new ConstraintOptions(); constraint.Convex = true; Mesh meshPlanning = (Mesh)mesher.Triangulate(polygon, constraint); TriangleQuadTree meshTree = new TriangleQuadTree(meshPlanning); TriangleNet.Topology.Triangle trgl = (TriangleNet.Topology.Triangle)meshTree.Query(X, Y); if (trgl == null) { Dictionary <Vertex, double> valuePairs = new Dictionary <Vertex, double>(); Line2d ln; foreach (Vertex item in meshPlanning.Vertices) { ln = new Line2d(new Point2d(X, Y), new Point2d(item.X, item.Y)); valuePairs.Add(item, ln.Length); } IOrderedEnumerable <KeyValuePair <Vertex, double> > selected = from v in valuePairs // определяем каждый объект как orderby v.Value // упорядочиваем по возрастанию select v; // выбираем объект List <KeyValuePair <Vertex, double> > lst = selected.ToList(); foreach (TriangleNet.Topology.Triangle item in meshPlanning.Triangles) { if (item.Contains(lst[0].Key) && item.Contains(lst[1].Key)) { trgl = item; break; } } } vrtx = new Vertex(X, Y, Number, 2); Interpolation.InterpolateAttributes(vrtx, trgl, 1); DL = Math.Round(vrtx.Attributes[0], 3); }
public void RegeneratePolygon() { polygon = new TriangleNet.Geometry.Polygon(parts.Count); foreach (var part in parts) { if (part.IsHole) { polygon.Add(part.contour, part.IsHole); } } foreach (var part in parts) { if (!part.IsHole) { polygon.Add(part.contour, part.IsHole); } } }
public Polygon(List <PolygonPart> parts) { this.parts = parts; polygon = new TriangleNet.Geometry.Polygon(parts.Count); foreach (var part in parts) { polygon.Add(part.contour, part.IsHole); } }
//create 2D Delauny Triangulation out of the planeCoords[] void StartDelaunayTriangulation() { TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon(); for (int i = 0; i < planeCoords.Length; i++) { polygon.Add(new TriangleNet.Geometry.Vertex(planeCoords[i].x, planeCoords[i].z)); } TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = false }; generatedMesh = (TriangleNet.Mesh)polygon.Triangulate(options); }
List <PopulationCentreConnection> getNearestNeighbourConnections(List <PopulationCentre> pops, RoadType roadType, List <PopulationCentreConnection> connections = null) { var geometry = new TriangleNet.Geometry.Polygon(); //Dictionary<Vertex, PopulationCentre> popDictionary = new Dictionary<Vertex, PopulationCentre>(); var connectionList = new List <PopulationCentreConnection>(); foreach (var pop in pops) { var vertex = new Vertex(pop.Position.x, pop.Position.y); //popDictionary.Add(vertex, pop); geometry.Add(vertex); } var mesh = geometry.Triangulate(); int org, dest; ITriangle neighbor; int nid; foreach (var tri in mesh.Triangles) { for (int i = 0; i < 3; i++) { // The neighbor opposite of vertex i. GetNeighbor(tri, i, out neighbor, out nid); // Consider each edge only once. if ((tri.ID < nid) || (nid < 0)) { // Get the edge endpoints. org = tri.GetVertexID((i + 1) % 3); dest = tri.GetVertexID((i + 2) % 3); var pop1 = pops[org]; var pop2 = pops[dest]; var connection = new PopulationCentreConnection(pop1, pop2); connection.roadType = roadType; if (connections == null || !connections.Any(x => x.Equal(connection))) { connectionList.Add(connection); } } } } return(connectionList); }
public void GenerateMeshData(ConstraintOptions options) { var polygon = new TriangleNet.Geometry.Polygon(); vertices = surroundingCorners .Where(corner => isFaceBorderCorner | corner != borderCorner) .Select(corner => corner.vertex - vertex) .OrderBy(difference => difference.GetAngle()) .ToArray(); normals = new Vertex[vertices.Length]; for (int q = 0; q < vertices.Length; q++) { Vertex v0 = vertices[q]; Vertex v1 = vertices[(q + 1) % vertices.Length]; normals[q] = (v1 - v0).Perpendicular().Normalize(); } foreach (Vertex vertex in vertices) { polygon.Add(vertex); } Mesh mesh = (Mesh)polygon.Triangulate(options); triangles = new int[mesh.triangles.Count * 3]; int index = 0; // if conforming delauny is off Id should eqaul index // if not I will have to develop a work around foreach (var triangle in mesh.triangles) { var vertices = triangle.vertices; triangles[index * 3] = vertices[2].id; triangles[index * 3 + 1] = vertices[1].id; triangles[index * 3 + 2] = vertices[0].id; index++; } }
public override IPolygon Generate(double param0, double param1, double param2) { int numPoints = GetParamValueInt(0, param0); numPoints = (numPoints / 10) * 10; if (numPoints < 5) { numPoints = 5; } double exp = (param1 + 10) / 100; var input = new Polygon(numPoints); int i = 0, cNum = 2 * (int)Math.Floor(Math.Sqrt(numPoints)); double r, phi, radius = 100, step = 2 * Math.PI / cNum; // Distrubute points equally on circle border for (; i < cNum; i++) { // Add a little error r = Util.Random.NextDouble(); input.Add(new Vertex((radius + r) * Math.Cos(i * step), (radius + r) * Math.Sin(i * step))); } for (; i < numPoints; i++) { // Use sqrt(rand) to get normal distribution right. r = Math.Pow(Util.Random.NextDouble(), exp) * radius; phi = Util.Random.NextDouble() * Math.PI * 2; input.Add(new Vertex(r * Math.Cos(phi), r * Math.Sin(phi))); } return input; }
public override IPolygon Generate(double param0, double param1, double param2) { int numPoints = GetParamValueInt(0, param0); numPoints = (numPoints / 10) * 10; if (numPoints < ranges[0][0]) { numPoints = ranges[0][0]; } var input = new Polygon(numPoints); int width = GetParamValueInt(1, param1); int height = GetParamValueInt(2, param2); for (int i = 0; i < numPoints; i++) { input.Add(new Vertex(Util.Random.NextDouble() * width, Util.Random.NextDouble() * height)); } return input; }
private static Mesh GetTriangleDotNetMesh(List <Vector2[]> poly_vertices) { var num_vxs = 0; foreach (var ring_vxs in poly_vertices) { num_vxs += ring_vxs.Length + 1; } var poly = new TriangleNet.Geometry.Polygon(num_vxs); // set vertices var ri = 0; foreach (var ring_vxs in poly_vertices) { var vxs_input = new List <TriangleNet.Geometry.Vertex>(ring_vxs.Length + 1); foreach (var vx in ring_vxs) { vxs_input.Add(new TriangleNet.Geometry.Vertex(vx.x, vx.y)); } // add to poly bool is_hole = ri != 0; var contour = new TriangleNet.Geometry.Contour(vxs_input); poly.Add(contour, is_hole); ++ri; } // triangulate var opts = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; var tn_mesh = (TriangleNet.Mesh)poly.Triangulate(opts); // write var tri_vxs = new Vector3[tn_mesh.Triangles.Count * 3]; var tri_ids = new int[tn_mesh.Triangles.Count * 3]; int i = 0; foreach (var tri in tn_mesh.Triangles) { tri_vxs[i + 0] = new Vector3((float)tri.GetVertex(0).x, (float)tri.GetVertex(0).y, 0); tri_vxs[i + 1] = new Vector3((float)tri.GetVertex(2).x, (float)tri.GetVertex(2).y, 0); tri_vxs[i + 2] = new Vector3((float)tri.GetVertex(1).x, (float)tri.GetVertex(1).y, 0); tri_ids[i + 0] = i + 0; tri_ids[i + 1] = i + 1; tri_ids[i + 2] = i + 2; i += 3; } // create mesh var m = new Mesh(); // assign to mesh m.vertices = tri_vxs; m.triangles = tri_ids; // recompute geometry // QUESTION why do we need bounds? m.RecalculateNormals(); m.RecalculateBounds(); return(m); }
public override List <SubdividableEdgeLoop <CityEdge> > GetChildren(SubdividableEdgeLoop <CityEdge> parent) { Vector2[] parentPoints = parent.GetPoints(); Polygon parentPoly = parent.GetPolygon(); //generate points of interest List <RoadDestination> pointsOfInterest = new List <RoadDestination>(); Vector2 centroid = parent.GetCenter(); //parent.EnumerateEdges((EdgeLoopEdge edge) => //{ // pointsOfInterest.Add(new RoadDestination(Vector2.Lerp(edge.a.pt, edge.b.pt, Random.Range(0.2f, 0.8f)), 1, false, true)); //}); Rect bounds = parent.GetBounds(); bounds.width = bounds.width * 2; bounds.height = bounds.height * 2; int potentialRoadPointsRt = Mathf.CeilToInt(Mathf.Sqrt(potentialRoadPoints)); float approxDiameter = Mathf.Sqrt(parentPoly.area); float minimumPerimeterDistance = approxDiameter / 4f; for (int x = 0; x < potentialRoadPointsRt; x++) { for (int y = 0; y < potentialRoadPointsRt; y++) { Vector2 point = new Vector2((x / (float)potentialRoadPointsRt) * bounds.width + bounds.xMin, (y / (float)potentialRoadPointsRt) * bounds.height + bounds.yMin); float distBtwnPts = (bounds.width + bounds.height) / (potentialRoadPoints * 2); point = point + new Vector2(Random.Range(-1f, 1f), Random.Range(-1, 1f)) * distBtwnPts * 3f; if (parentPoly.ContainsPoint(point)) // && parent.DistToPerimeter(point) > minimumPerimeterDistance) { pointsOfInterest.Add(new RoadDestination(point, 0, false, false)); } } } pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(bounds.width * 100, bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(bounds.width * 100, -bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(-bounds.width * 100, -bounds.height * 100), 0, false, false)); pointsOfInterest.Add(new RoadDestination(bounds.center + new Vector2(-bounds.width * 100, bounds.height * 100), 0, false, false)); //triangulate points of interest to get potential road segments TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon(); Dictionary <TriangleNet.Geometry.Vertex, RoadDestination> vertexDestMap = new Dictionary <TriangleNet.Geometry.Vertex, RoadDestination>(); foreach (RoadDestination dest in pointsOfInterest) { TriangleNet.Geometry.Vertex vert = new TriangleNet.Geometry.Vertex(dest.point.x, dest.point.y); vertexDestMap.Add(vert, dest); polygon.Add(vert); } TriangleNet.Meshing.ConstraintOptions options = new TriangleNet.Meshing.ConstraintOptions() { ConformingDelaunay = true }; TriangleNet.Meshing.GenericMesher mesher = new TriangleNet.Meshing.GenericMesher(); TriangleNet.Meshing.IMesh mesh = mesher.Triangulate(polygon); TriangleNet.Voronoi.StandardVoronoi voronoi = new TriangleNet.Voronoi.StandardVoronoi((TriangleNet.Mesh)mesh); IEnumerable <TriangleNet.Geometry.IEdge> voronoiEdges = voronoi.Edges; List <TriangleNet.Topology.DCEL.Vertex> voronoiVerts = voronoi.Vertices; List <DividingEdge> dividingEdges = new List <DividingEdge>(); ILinkedGraphEdgeFactory <CityEdge> factory = new CityEdgeFactory(); foreach (TriangleNet.Geometry.IEdge edge in voronoiEdges) { Vector2 a = new Vector2((float)voronoiVerts[edge.P0].X, (float)voronoiVerts[edge.P0].Y); Vector2 b = new Vector2((float)voronoiVerts[edge.P1].X, (float)voronoiVerts[edge.P1].Y); dividingEdges.Add(new DividingEdge(a, b, factory, factoryParams)); } //get vertices as list //ICollection<TriangleNet.Geometry.Vertex> vertices = mesh.Vertices; //TriangleNet.Geometry.Vertex[] vertexList = new TriangleNet.Geometry.Vertex[vertices.Count]; //vertices.CopyTo(vertexList, 0); //IEnumerable<TriangleNet.Geometry.Edge> meshEdges = mesh.Edges; //build a list of dividing edges and pass it to the child collector //foreach (TriangleNet.Geometry.Edge edge in meshEdges) { // //if (vertConnections[edge.P0] > 4) // //{ // // vertConnections[edge.P0]--; // // continue; // //} // //if (vertConnections[edge.P1] > 4) // //{ // // vertConnections[edge.P1]--; // // continue; // //} // Vector2 a = new Vector2((float)vertexList[edge.P0].X, (float)vertexList[edge.P0].Y); // Vector2 b = new Vector2((float)vertexList[edge.P1].X, (float)vertexList[edge.P1].Y); // dividingEdges.Add(new DividingEdge(a, b, factory, CityEdgeType.LandPath)); //} return(CollectChildren(parent, dividingEdges)); }
private void button5_Click(object sender, EventArgs e) { var poly2 = new TriangleNet.Geometry.Polygon(); var plh = dataModel.SelectedItem as PolygonHelper; //foreach (var item in plh.Polygon.Points) { var pn = plh.TransformedPoints(); if (StaticHelpers.signed_area(pn) < 0) { pn = pn.Reverse().ToArray(); } var a = pn.Select(z => new Vertex(z.X, z.Y, 0)).ToArray(); poly2.Add(new Contour(a)); } var rev = plh.Polygon.Childrens.ToArray(); rev = rev.Reverse().ToArray(); foreach (var item in rev) { var pn = item.Points.Select(z => plh.Transform(z)).ToArray(); var ar = StaticHelpers.signed_area(pn); /*if (StaticHelpers.signed_area(pn) > 0) * { * pn = pn.Reverse().ToArray(); * }*/ var a = pn.Select(z => new Vertex(z.X, z.Y, 0)).ToArray(); var p0 = plh.Transform(item.Points[0]); PointF test = new PointF((float)p0.X, (float)p0.Y); var maxx = pn.Max(z => z.X); var minx = pn.Min(z => z.X); var maxy = pn.Max(z => z.Y); var miny = pn.Min(z => z.Y); var tx = rand.Next((int)(minx * 100), (int)(maxx * 100)) / 100f; var ty = rand.Next((int)(miny * 100), (int)(maxy * 100)) / 100f; while (true) { if (StaticHelpers.pnpoly(pn, test.X, test.Y)) { break; } tx = rand.Next((int)(minx * 100), (int)(maxx * 100)) / 100f; ty = rand.Next((int)(miny * 100), (int)(maxy * 100)) / 100f; test = new PointF(tx, ty); } poly2.Add(new Contour(a), new TriangleNet.Geometry.Point(test.X, test.Y)); //poly2.Add(new Contour(a), true); } var trng = (new GenericMesher()).Triangulate(poly2, new ConstraintOptions(), new QualityOptions()); var tr = trng.Triangles.Select(z => new PointF[] { new PointF((float)z.GetVertex(0).X, (float)z.GetVertex(0).Y), new PointF((float)z.GetVertex(1).X, (float)z.GetVertex(1).Y), new PointF((float)z.GetVertex(2).X, (float)z.GetVertex(2).Y) }).ToArray(); dataModel.AddItem(new MeshHelper(tr) { Name = "triangulate" }); }
private void Triangulate_Click(object sender, RoutedEventArgs e) { var qualityOptions = new TriangleNet.Meshing.QualityOptions(); qualityOptions.MaximumArea = double.Parse(hTextBox.Text); qualityOptions.MinimumAngle = double.Parse(LTextBox.Text); var objct = new TriangleNet.Geometry.Polygon(); foreach (var item in mycoordinates) { objct.Add(item); } for (int i = 0; i < mycoordinates.Count - 1; i++) { objct.Add(new Segment(mycoordinates[i], mycoordinates[i + 1])); } objct.Add(new Segment(mycoordinates.LastOrDefault(), mycoordinates.FirstOrDefault())); //var test = new TriangleNet.Meshing.Algorithm.SweepLine(); var constraintOption = new TriangleNet.Meshing.ConstraintOptions(); meshResult = objct.Triangulate(constraintOption, qualityOptions, new TriangleNet.Meshing.Algorithm.Incremental()); //Triangulation //meshResult = objct.Triangulate(qualityOptions); meshResult.Renumber(); //triangleResult = new List<TriangleNet.Topology.Triangle>(meshResult.Triangles); //Triangles trianglesResult = GetTrianglesFromMeshTriangles(meshResult.Triangles); resultsTriangles.ItemsSource = trianglesResult; //Vertices verticesResult = new List <Vertex>(meshResult.Vertices); myvertixesResult = meshResult.Vertices.Select(v => new MyVertex { Id = v.ID, X = v.X, Y = v.Y }).ToList(); results.ItemsSource = myvertixesResult; //Заповнення граничних сегментів for (int i = 0; i < boundaries.Count; i++) { boundaries[i].SetSegments(meshResult.Segments, boundaries.Count); } //Перетворення орієнтації всіх сегментів проти годинникової стрілки for (int i = 0; i < boundaries.Count; i++) { if (i != boundaries.Count - 1) { boundaries[i].SetSegmentsOrientationToCounterclockwise(i, i + 1); } else { boundaries[i].SetSegmentsOrientationToCounterclockwise(i, 0); } } // FillGridWithBoundaries(resultsBoundaries, boundaries); DrawData(meshResult); //Етап 2: Створення матриць Me, Ke, Qe, Re, Pe //Підготовка //Зчитування параметрів double a11 = double.Parse(a11TextBox.Text); double a22 = double.Parse(a22TextBox.Text); double d = double.Parse(dTextBox.Text); double f = double.Parse(fTextBox.Text); //Створення масиву точок var CT = GetPointsArray(myvertixesResult); //Створення масиву трикутників var NT = GetTrianglesArray(trianglesResult); //Створення масиву граничних сегментів var NTGR = GetBoundarySegments(boundaries); //Створення масиву значень ф-кції f у точках var fe = GetFe(CT, f); //Етап 3 (ініціалізація A,B) //Кількість вузлів int nodeNumber = CT.Length; var A = new double[nodeNumber][]; for (int i = 0; i < nodeNumber; i++) { A[i] = new double[nodeNumber]; } var b = new double[nodeNumber]; //Створення Me, Ke, Qe (та їх розсилання) double[] function_value = new double[3]; for (int k = 0; k < trianglesResult.Count; k++) { //трикутник містить координати вузлів скінченного елемента var triangle = NT[k]; //Підготовка double[] i = CT[triangle[0]], j = CT[triangle[1]], m = CT[triangle[2]]; double Se = GetArea(i, j, m); double ai = GetA(j, m), bi = GetB(j, m), ci = GetC(j, m), aj = GetA(m, i), bj = GetB(m, i), cj = GetC(m, i), am = GetA(i, j), bm = GetB(i, j), cm = GetC(i, j); double[] a = new double[] { ai, aj, am }, B = new double[] { bi, bj, bm }, c = new double[] { ci, cj, cm }; function_value[0] = fe[triangle[0]]; function_value[1] = fe[triangle[1]]; function_value[2] = fe[triangle[2]]; //Ke var ke = new KE(k, Se, a11, a22, B, c); ke.print(); //Me var me = new ME(k, Se, d); me.print(); //Qe var qe = new QE(k, Se, fe); qe.print(); //Етап 3 for (int q = 0; q < 3; q++) { //triangle[q] це номер вузла елемента for (int w = 0; w < 3; w++) { A[triangle[q]][triangle[w]] += ke.Ke[q][w] + me.Me[q][w]; } b[triangle[q]] += qe.Qe[q][0]; } } //Створення Re, Pe (та їх розсилання) for (int k = 0; k < boundaries.Count; k++) { for (int l = 0; l < NTGR[k].Length; l++) { //сегмент містить координати вузлів граничного сегмента var segment = NTGR[k][l]; //Підготовка double[] i = CT[NTGR[k][l][0]], j = CT[NTGR[k][l][1]]; double Length = GetLength(i, j); //Re var re = new RE(k + l, boundaries[k].G, boundaries[k].B, Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]); re.print(); //Pe var pe = new PE(k + l, boundaries[k].G, boundaries[k].B, boundaries[k].Uc, Length, k + "|" + l + "|" + NTGR[k][l][0] + "-" + NTGR[k][l][1]); pe.print(); //Етап 3 for (int q = 0; q < 2; q++) { //segment[q] це номер вузла сегмента for (int w = 0; w < 2; w++) { A[segment[q]][segment[w]] += re.Re[q][w]; } b[segment[q]] += pe.Pe[q][0]; } } } //Запис у файл A,b print(A, b); //Етап 3-2 var u = GausseMethod(nodeNumber, A, b); printNonFormatted(CT, u, "results.txt"); }
private void ReadPoints(Polygon geometry, Dictionary<string, object> points, ref int count) { ArrayList data = points["data"] as ArrayList; ArrayList markers = null; ArrayList attributes = null; if (points.ContainsKey("markers")) { markers = points["markers"] as ArrayList; } if (points.ContainsKey("attributes")) { attributes = points["attributes"] as ArrayList; } if (data != null) { int mark, n = data.Count; if (n % 2 != 0) { throw new Exception("JSON format error (points)."); } // Number of points count = n / 2; for (int i = 0; i < n; i += 2) { mark = 0; if (markers != null && markers.Count == count) { mark = int.Parse(markers[i / 2].ToString()); } geometry.Add(new Vertex( double.Parse(data[i].ToString(), Util.Nfi), double.Parse(data[i + 1].ToString(), Util.Nfi), mark )); } } }
public override IPolygon Generate(double param0, double param1, double param2) { int numRays = GetParamValueInt(0, param0); var g = new Polygon(numRays + 4); g.Add(new Vertex(0, 0)); // Center double x, y, r, e, step = 2 * Math.PI / numRays; for (int i = 0; i < numRays; i++) { e = Util.Random.NextDouble() * step * 0.7; r = (Util.Random.NextDouble() + 0.7) * 0.5; x = r * Math.Cos(i * step + e); y = r * Math.Sin(i * step + e); g.Add(new Vertex(x, y, 2)); g.Add(new Segment(g.Points[0], g.Points[i + 1], 2)); } g.Add(new Vertex(-1, -1, 1)); // Box g.Add(new Vertex(1, -1, 1)); g.Add(new Vertex(1, 1, 1)); g.Add(new Vertex(-1, 1, 1)); numRays = g.Count; g.Add(new Segment(g.Points[numRays - 1], g.Points[numRays - 2], 1)); g.Add(new Segment(g.Points[numRays - 2], g.Points[numRays - 3], 1)); g.Add(new Segment(g.Points[numRays - 3], g.Points[numRays - 4], 1)); g.Add(new Segment(g.Points[numRays - 4], g.Points[numRays - 1], 1)); return g; }
protected override void ProcessContext(Canvas canvas, List <Point> points) { if (points.Count < 3) { return; } var options = new ConstraintOptions(); options.ConformingDelaunay = true; var quality = new QualityOptions(); quality.MinimumAngle = MinAngel; quality.MaximumArea = MaxSquare; var polygon = new TriangleNet.Geometry.Polygon(); points.ForEach(p => polygon.Add(new Vertex(p.X, p.Y))); for (int i = 0; i < points.Count - 1; i++) { polygon.Add(new Segment(new Vertex(points[i].X, points[i].Y), new Vertex(points[i + 1].X, points[i + 1].Y))); } Point last = points.LastOrDefault(); Point first = points.FirstOrDefault(); polygon.Add(new Segment(new Vertex(last.X, last.Y), new Vertex(first.X, first.Y))); var mesh = polygon.Triangulate(options, quality); this.mesh = mesh; if (mesh != null) { mesh.Refine(quality, true); } this.mesh.Renumber(); foreach (ITriangle triangle in mesh.Triangles) { Point p1 = new Point { X = (triangle.GetVertex(0).X + 1) * 100, Y = (triangle.GetVertex(0).Y + 1) * 100, ID = triangle.GetVertex(0).ID }; Point p2 = new Point { X = (triangle.GetVertex(1).X + 1) * 100, Y = (triangle.GetVertex(1).Y + 1) * 100, ID = triangle.GetVertex(1).ID }; Point p3 = new Point { X = (triangle.GetVertex(2).X + 1) * 100, Y = (triangle.GetVertex(2).Y + 1) * 100, ID = triangle.GetVertex(2).ID }; Triangle myTriangle = new Triangle { Points = new List <Point> { p1, p2, p3 }, SegmentId = triangle.ID }; myTriangle.Stroke = Brushes.Black; myTriangle.MouseEnter += (sender, e) => { MouseEnterAction(sender, e); }; myTriangle.MouseLeave += (sender, e) => { MouseLeaveAction(sender, e); }; myTriangle.MouseDown += (sender, e) => { MouseUp(sender, e); }; if (canvas != null) { canvas.Children.Add(myTriangle); } } }