public static void ComputeCornerArea(TriMesh mesh, out double[] CornerArea, out double[] PointArea) { CornerArea = new double[mesh.HalfEdges.Count]; PointArea = new double[mesh.Vertices.Count]; foreach (var face in mesh.Faces) { double area = TriMeshUtil.ComputeAreaFace(face); TriMesh.HalfEdge[] hf = new HalfEdgeMesh.HalfEdge[] { face.HalfEdge, face.HalfEdge.Next, face.HalfEdge.Previous }; int[] index = new int[3]; for (int i = 0; i < 3; i++) { index[i] = hf[i].Index; } Vector3D[] e = new Vector3D[3]; for (int i = 0; i < 3; i++) { e[i] = TriMeshUtil.GetHalfEdgeVector(hf[i].Previous); } double[] l2 = new double[3]; for (int i = 0; i < 3; i++) { l2[i] = e[i].LengthSquared; } double[] ew = new double[3]; for (int i = 0; i < 3; i++) { ew[i] = l2[i] * (l2[(i + 1) % 3] + l2[(i + 2) % 3] - l2[i]); } bool flag = false; for (int i = 0; i < 3; i++) { if (ew[i] < 0d) { int a = (i + 1) % 3; int b = (i + 2) % 3; CornerArea[index[a]] = -0.25d * l2[b] * area / e[i].Dot(e[b]); CornerArea[index[b]] = -0.25d * l2[a] * area / e[i].Dot(e[a]); CornerArea[index[i]] = area - CornerArea[index[a]] - CornerArea[index[b]]; flag = true; } } if (!flag) { double ewscale = 0.5d * area / (ew[0] + ew[1] + ew[2]); for (int i = 0; i < 3; i++) { CornerArea[index[i]] = ewscale * (ew[(i + 1) % 3] + ew[(i + 2) % 3]); } } for (int i = 0; i < 3; i++) { PointArea[hf[i].ToVertex.Index] += CornerArea[index[i]]; } } }