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

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

则在第一次循环时可以得到如下结果

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

                     

大概思路应该知道了,下面上代码:

  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         }

 还有很多其他实现方法,比如二分法,如果是凸边形也可以用扇形分解法。