Esempio n. 1
0
        internal bool InsertPoint(Point2d x, double space, out AM_Vertex pvertex)
        {
            pvertex = null;
            AM_Face face = null;

            // Localizza uno spigolo vicino
            AM_Edge edge = Locate(x);

            if (edge == null)
            {
                return(false);
            }

            // Localizza il triangolo che contiene il punto x
            // e imposta 'm_pStartingEdge', primo spigolo del triangolo o del quadrilatero
            // che deve essere riconnesso al punto x
            if (AM_Edge.LeftOf(x, edge))
            {
                face           = (AM_Face)(edge.CcwFace());
                m_StartingEdge = edge.CcwEdge();
            }
            else
            {
                face           = (AM_Face)(edge.CwFace());
                m_StartingEdge = edge.Symm().CcwEdge();
            }

            if (face == null)
            {
                return(false);
            }

            // Verifica dell'eventuale esistenza del punto
            if (x == edge.OrgCoord())
            {
                pvertex = edge.Origin();
                return(false);
            }

            if (x == edge.DestCoord())
            {
                pvertex = edge.Destination();
                return(false);
            }

            Point2d[] v1 = { face.Vertex(0).Coord, face.Vertex(1).Coord, face.Vertex(2).Coord, };

            //isOnEdge = OnEdge(x, edge);
            AM_Edge pOnEdge = OnFaceEdge(x, face);

            if (pOnEdge != null)
            {
                m_StartingEdge = pOnEdge.CcwEdge();

                // il punto si trova su un contorno!
                AM_Face pCwFace  = pOnEdge.CwFace();
                AM_Face pCcwFace = pOnEdge.CcwFace();

                if (pCwFace == null || pCcwFace == null)
                {
                    return(false);
                }
            }

            // Il punto è all'interno di un triangolo o su uno spigolo
            if (face.FaceType == AM_Face.EFaceType.FT_ACTIVE)
            {
                DeleteActiveFace(face);
            }

            DeleteFace(face);
            if (pOnEdge != null)
            {
                // Cancella lo spigolo su cui si appoggia e
                // conseguentemente anche l'altro spigolo

                AM_Face pCwFace  = pOnEdge.CwFace();
                AM_Face pCcwFace = pOnEdge.CcwFace();

                if (pCwFace != null && pCwFace.FaceType == AM_Face.EFaceType.FT_ACTIVE)
                {
                    DeleteActiveFace(pCwFace);
                }
                if (pCcwFace != null && pCcwFace.FaceType == AM_Face.EFaceType.FT_ACTIVE)
                {
                    DeleteActiveFace(pCcwFace);
                }

                DeleteEdge(pOnEdge);
            }

            // Inserisce il nuovo vertice nell'array globale
            pvertex = new AM_Vertex(x, 0, space);
            if (pvertex == null)
            {
                Debug.Assert(false);
                //throw -1;
            }


            int m_nVertex = m_ArrayVertexes.Count;

            pvertex.Index = m_ArrayVertexes.Count;
            m_ArrayVertexes.Add(pvertex);

            // Inserisce i nuovi triangoli (facce)
            edge = m_StartingEdge.CcwEdge();
            int numEdge = (pOnEdge != null? 4 : 3);

            for (int ne = 0; ne < numEdge; ne++)
            {
                AM_Face new_face = new AM_Face();
                if (new_face == null)
                {
                    Debug.Assert(false);
                    //throw -1;
                }

                AM_Edge actEdge = edge;
                edge = edge.CcwEdge();
                int [] nCoord = { m_nVertex, actEdge.Vertex.Index, actEdge.DestVertex().Index };
                AddFace(new_face, nCoord);

                if (m_bFlagClassific)
                {
                    new_face.SetTriangleParameter(m_pSpaceFunction);
                    Classific(new_face);
                }
            }

            // Esamina gli spigoli per assicurare che la condizione di
            // Delaunay sia soddisfatta
            edge           = m_StartingEdge;
            m_StartingEdge = m_StartingEdge.CcwEdge();
            do
            {
                //TRACE_EDGE(edge);
                AM_Edge t = edge.Prev;
                if (edge.CwFace() != null && AM_Edge.RightOf(t.DestCoord(), edge) &&
                    AM_Util.InCircle(edge.OrgCoord(), t.DestCoord(), edge.DestCoord(), x))
                {
                    //TRACE0("Faccia swap:  ");
                    //TRACE_EDGE(edge);
                    Swap(edge);
                    edge = edge.Prev;
                }
                else if (edge.Next == m_StartingEdge)
                {
                    // Non ci sono più spigoli
                    break;
                }
                else
                {
                    // Recupera un altro spigolo sospetto
                    edge = edge.Next.CwEdge();
                }
            } while (true);

            return(true);
        }