看下面多边形,比较复杂的一个多边形,如何实现三角化

以左上角点为第一个点,依次向后找两个点,看是否能够连接成合法的三角形,合法的三角形即三角形在多边形内部且不能与多边形边有相交(相交在端点不算)
则在第一次循环时可以得到如下结果

接着在得到的新的多边形上重复上一次操作,重复多次直到剩下三个点,最后三个点构成三角形。那么任意多边形三角化工作就结束了。



大概思路应该知道了,下面上代码:
1 private void GetTriangleResult(List<SingleModel> modelList, int i, ref int tempCount, ref ModelMesh mesh, ref List<int> group, List<SingleModel> modelListDL) 2 { 3 List<double[]> coorData = new List<double[]>(); 4 for (int j = 0; j < modelListDL[i].coordinates.Count; j++)//使用未平铺处理之前的点 5 { 6 double x = (modelListDL[i].coordinates[j][0] - centerDL.X) * longMeter; 7 double y = (modelListDL[i].coordinates[j][1] - centerDL.Y) * GetLatMeter(centerDL.Y); 8 coorData.Add(new double[] { x, y }); 9 } 10 11 Cartesian3 minfloor = GetMinXY(coorData); 12 Cartesian3 maxfloor = GetMaxXY(coorData); 13 14 while (coorData.Count > 3) 15 { 16 for (int idx = 0; idx < coorData.Count - 3; idx++) 17 { 18 double[] pointTemp = new double[] { (coorData[idx][0] + coorData[idx + 2][0]) / 2, (coorData[idx][1] + coorData[idx + 2][1]) / 2 }; 19 if (coorData.Count == 4) 20 { 21 Vertex vertexDD1 = new Vertex(); 22 vertexDD1.x = coorData[idx][0]; 23 vertexDD1.y = coorData[idx][1]; 24 vertexDD1.z = modelListDL[i].floor * floorHeight; 25 vertexDD1.tu = (vertexDD1.x - minfloor.X) / (maxfloor.X - minfloor.X); 26 vertexDD1.tv = (vertexDD1.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 27 vertexDD1.Normal = new Cartesian3(0, 0, 1); 28 29 Vertex vertexDD2 = Vertex.Clone(vertexDD1); 30 vertexDD2.x = coorData[idx + 1][0]; 31 vertexDD2.y = coorData[idx + 1][1]; 32 vertexDD2.tu = (vertexDD2.x - minfloor.X) / (maxfloor.X - minfloor.X); 33 vertexDD2.tv = (vertexDD2.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 34 35 Vertex vertexDD3 = Vertex.Clone(vertexDD1); 36 vertexDD3.x = coorData[idx + 2][0]; 37 vertexDD3.y = coorData[idx + 2][1]; 38 vertexDD3.tu = (vertexDD3.x - minfloor.X) / (maxfloor.X - minfloor.X); 39 vertexDD3.tv = (vertexDD3.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 40 41 mesh.Vertexes.Add(vertexDD1); 42 mesh.Vertexes.Add(vertexDD2); 43 mesh.Vertexes.Add(vertexDD3); 44 45 coorData.RemoveAt(idx + 1); 46 47 mesh.indices.Add(new int[3] { tempCount + 1, tempCount + 2, tempCount + 3 }); 48 49 tempCount = mesh.Vertexes.Count; 50 group.Add(i * 3 + 2); 51 } 52 else if (!IsPointInRange(pointTemp, coorData)) 53 { 54 continue; 55 } 56 else 57 { 58 List<double[]> triangle = new List<double[]>(); 59 triangle.Add(coorData[idx]); 60 triangle.Add(coorData[idx + 1]); 61 triangle.Add(coorData[idx + 2]); 62 63 if (IsExistPointInTriangle(triangle, coorData)) 64 { 65 continue; 66 } 67 else 68 { 69 Vertex vertexDD1 = new Vertex(); 70 vertexDD1.x = coorData[idx][0]; 71 vertexDD1.y = coorData[idx][1]; 72 vertexDD1.z = modelListDL[i].floor * floorHeight; 73 vertexDD1.tu = (vertexDD1.x - minfloor.X) / (maxfloor.X - minfloor.X); 74 vertexDD1.tv = (vertexDD1.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 75 vertexDD1.Normal = new Cartesian3(0, 0, 1); 76 77 Vertex vertexDD2 = Vertex.Clone(vertexDD1); 78 vertexDD2.x = coorData[idx + 1][0]; 79 vertexDD2.y = coorData[idx + 1][1]; 80 vertexDD2.tu = (vertexDD2.x - minfloor.X) / (maxfloor.X - minfloor.X); 81 vertexDD2.tv = (vertexDD2.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 82 83 Vertex vertexDD3 = Vertex.Clone(vertexDD1); 84 vertexDD3.x = coorData[idx + 2][0]; 85 vertexDD3.y = coorData[idx + 2][1]; 86 vertexDD3.tu = (vertexDD3.x - minfloor.X) / (maxfloor.X - minfloor.X); 87 vertexDD3.tv = (vertexDD3.y - minfloor.Y) / (maxfloor.Y - minfloor.Y); 88 89 mesh.Vertexes.Add(vertexDD1); 90 mesh.Vertexes.Add(vertexDD2); 91 mesh.Vertexes.Add(vertexDD3); 92 93 coorData.RemoveAt(idx + 1); 94 95 mesh.indices.Add(new int[3] { tempCount + 1, tempCount + 2, tempCount + 3 }); 96 97 tempCount = mesh.Vertexes.Count; 98 group.Add(i * 3 + 2); 99 } 100 } 101 } 102 } 103 }
还有很多其他实现方法,比如二分法,如果是凸边形也可以用扇形分解法。
浙公网安备 33010602011771号