// from http://www.geometry.caltech.edu/pubs/DMSB_III.pdf public static double VoronoiArea(NGonsCore.geometry3Sharp.mesh.DMesh3 mesh, int v_i) { double areaSum = 0; Vector3D Vi = mesh.GetVertex(v_i); foreach (int tid in mesh.VtxTrianglesItr(v_i)) { Index3i t = mesh.GetTriangle(tid); int ti = (t[0] == v_i) ? 0 : ((t[1] == v_i) ? 1 : 2); Vector3D Vj = mesh.GetVertex(t[(ti + 1) % 3]); Vector3D Vk = mesh.GetVertex(t[(ti + 2) % 3]); if (math.MathUtil.IsObtuse(Vi, Vj, Vk)) { Vector3D Vij = Vj - Vi; Vector3D Vik = Vk - Vi; Vij.Normalize(); Vik.Normalize(); double areaT = 0.5 * Vij.Cross(Vik).Length; if (Vector3D.AngleR(Vij, Vik) > math.MathUtil.HalfPI) { areaSum += (areaT * 0.5); // obtuse at v_i } else { areaSum += (areaT * 0.25); // not obtuse } } else { // voronoi area Vector3D Vji = Vi - Vj; double dist_ji = Vji.Normalize(); Vector3D Vki = Vi - Vk; double dist_ki = Vki.Normalize(); Vector3D Vkj = (Vj - Vk).Normalized; double cot_alpha_ij = math.MathUtil.VectorCot(Vki, Vkj); double cot_alpha_ik = math.MathUtil.VectorCot(Vji, -Vkj); areaSum += dist_ji * dist_ji * cot_alpha_ij * 0.125; areaSum += dist_ki * dist_ki * cot_alpha_ik * 0.125; } } return(areaSum); }