Ejemplo n.º 1
0
        // 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);
        }