Ejemplo n.º 1
0
        // from http://www.geometry.caltech.edu/pubs/DMSB_III.pdf
        public static double VoronoiArea(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 (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) > 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 = MathUtil.VectorCot(Vki, Vkj);
                    double cot_alpha_ik = 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);
        }