Exemplo n.º 1
0
        /// <summary>
        /// Add new face to the tree
        /// </summary>
        /// <param name="newFace"></param>
        public void Add( Face newFace )
        {
            // add the face
            FaceTreeAdd( FaceRoot, newFace );

            // check if the face is boundary face
            if ( newFace.HalfEnd.TwinEdge == null ||
                 newFace.HalfEnd.NextEdge.TwinEdge == null ||
                 newFace.HalfEnd.NextEdge.NextEdge.TwinEdge == null ) {

                // add the face to the boundary
                BoundaryFaces.Add( newFace );

            }
        }
Exemplo n.º 2
0
        private void FaceTreeRemove(FaceDistTreeNode faceNode, Face newFace)
        {
            // check if we are in leaf
            if (faceNode.isLeaf)
            {

                // just remove the face to the list
                faceNode.FaceList.Remove(newFace);

            }
            else
            {
                // continue to the correct side
                if (newFace.Min_X > faceNode.X_mid)
                {
                    if (newFace.Min_Y > faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.UpRight, newFace);
                    }
                    else if (newFace.Max_Y < faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.DownRight, newFace);
                    }
                    else
                    {
                        // add in both sides :P
                        FaceTreeRemove(faceNode.UpRight, newFace);
                        FaceTreeRemove(faceNode.DownRight, newFace);
                    }
                }
                else if (newFace.Max_X < faceNode.X_mid)
                {
                    if (newFace.Min_Y > faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.UpLeft, newFace);
                    }
                    else if (newFace.Max_Y < faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.DownLeft, newFace);
                    }
                    else
                    {
                        // add in both sides :P
                        FaceTreeRemove(faceNode.UpLeft, newFace);
                        FaceTreeRemove(faceNode.DownLeft, newFace);
                    }

                }
                else
                {
                    if (newFace.Min_Y > faceNode.Y_mid)
                    {
                        // add in both sides
                        FaceTreeRemove(faceNode.UpRight, newFace);
                        FaceTreeRemove(faceNode.UpLeft, newFace);
                    }
                    else if (newFace.Max_Y < faceNode.Y_mid)
                    {
                        // add in both sides
                        FaceTreeRemove(faceNode.DownRight, newFace);
                        FaceTreeRemove(faceNode.DownLeft, newFace);
                    }
                    else
                    {
                        // add in all sides :P
                        FaceTreeRemove(faceNode.DownRight, newFace);
                        FaceTreeRemove(faceNode.DownLeft, newFace);
                        FaceTreeRemove(faceNode.UpRight, newFace);
                        FaceTreeRemove(faceNode.UpLeft, newFace);
                    }
                }
            }
        }
Exemplo n.º 3
0
        private void FaceTreeAdd(FaceDistTreeNode faceNode, Face newFace)
        {
            // check if we are in leaf
            if (faceNode.isLeaf)
            {
                // check if we are pass the max num of faces per leaf
                if (faceNode.FaceList.Count < MaxFaces)
                {
                    // just add the face to the list
                    faceNode.FaceList.Add(newFace);
                }
                else
                {
                    // split the leaf to 4 nodes
                    FaceNodeSpliting(faceNode);

                    // re-call this function as node
                    FaceTreeAdd(faceNode, newFace);
                }
            }
            else
            {
                // continue to the correct side
                if (newFace.Min_X >= faceNode.X_mid)
                {
                    if (newFace.Min_Y >=faceNode.Y_mid)
                    {
                        FaceTreeAdd(faceNode.UpRight, newFace);
                    }
                    else if (newFace.Max_Y <= faceNode.Y_mid)
                    {
                        FaceTreeAdd(faceNode.DownRight, newFace);
                    }
                    else
                    {
                        // add in both sides :P
                        FaceTreeAdd(faceNode.UpRight, newFace);
                        FaceTreeAdd(faceNode.DownRight, newFace);
                    }
                }
                else if (newFace.Max_X <= faceNode.X_mid)
                {
                    if (newFace.Min_Y >= faceNode.Y_mid)
                    {
                        FaceTreeAdd(faceNode.UpLeft, newFace);
                    }
                    else if (newFace.Max_Y <= faceNode.Y_mid)
                    {
                        FaceTreeAdd(faceNode.DownLeft, newFace);
                    }
                    else
                    {
                        // add in both sides :P
                        FaceTreeAdd(faceNode.UpLeft, newFace);
                        FaceTreeAdd(faceNode.DownLeft, newFace);
                    }

                }
                else
                {
                    if (newFace.Min_Y >= faceNode.Y_mid)
                    {
                        // add in both sides
                        FaceTreeAdd(faceNode.UpRight, newFace);
                        FaceTreeAdd(faceNode.UpLeft, newFace);
                    }
                    else if (newFace.Max_Y <= faceNode.Y_mid)
                    {
                        // add in both sides
                        FaceTreeAdd(faceNode.DownRight, newFace);
                        FaceTreeAdd(faceNode.DownLeft, newFace);
                    }
                    else
                    {
                        // add in all sides :P
                        FaceTreeAdd(faceNode.DownRight, newFace);
                        FaceTreeAdd(faceNode.DownLeft, newFace);
                        FaceTreeAdd(faceNode.UpRight, newFace);
                        FaceTreeAdd(faceNode.UpLeft, newFace);
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// remove the face from the tree
        /// </summary>
        /// <param name="oldFace"></param>
        public void Remove( Face oldFace )
        {
            // remove the face
            FaceTreeRemove( FaceRoot, oldFace );

            // check if the face is boundary face
            if ( oldFace.HalfEnd.TwinEdge == null ||
                 oldFace.HalfEnd.NextEdge.TwinEdge == null ||
                 oldFace.HalfEnd.NextEdge.NextEdge.TwinEdge == null ) {

                // add the face to the boundary
                BoundaryFaces.Remove( oldFace );

            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// update all the internal structs base on the specific struct
 /// </summary>
 public void Update( Face face )
 {
     // update all the internal face
     face.Update();
 }
Exemplo n.º 6
0
 /// <summary>
 /// remove the face from the tree
 /// </summary>
 /// <param name="oldFace"></param>
 public void Remove( Face oldFace )
 {
     // remove the face
     FaceList.Remove( oldFace );
 }
Exemplo n.º 7
0
 /// <summary>
 /// Add new face to the tree
 /// </summary>
 /// <param name="newFace"></param>
 public void Add( Face newFace )
 {
     FaceList.Add( newFace );
 }
Exemplo n.º 8
0
        /// <summary>
        /// Init the internal state
        /// </summary>
        /// <param name="ver1"></param>
        /// <param name="ver2"></param>
        /// <param name="ver3"></param>
        /// <param name="faceTree"></param>
        private void Init(IVertex<float> ver1, IVertex<float> ver2, IVertex<float> ver3, IFaceTree faceTree)
        {
            // init the face tree
            this.faceTree = faceTree;

            // ini the min max boundary
            BoundaryMinMax = new BoundaryNodeMaxMin();

            // add the 3 half edge
            Half_Edge he1, he2, he3;

            // crate the triangle
            Half_Edge.CreateTriangle(ver1, ver2, ver3,
                                      out he1, out he2, out he3);

            // create and link the boundary list
            {
                // create the boundary list
                RootBoundaryNode = new BoundaryNode(he1, true);
                BoundaryNode nextBoundaryNode1 = new BoundaryNode(he1.NextEdge);
                BoundaryNode nextBoundaryNode2 = new BoundaryNode(he1.NextEdge.NextEdge);

                // link the root with the next node
                RootBoundaryNode.NextNode = nextBoundaryNode1;
                nextBoundaryNode1.PrevNode = RootBoundaryNode;

                // link the root with the next node
                nextBoundaryNode1.NextNode = nextBoundaryNode2;
                nextBoundaryNode2.PrevNode = nextBoundaryNode1;

                // link the first with the last one
                nextBoundaryNode2.NextNode = RootBoundaryNode;
                RootBoundaryNode.PrevNode = nextBoundaryNode2;

                // select the min/max nodes
                {
                    // init min/max
                    BoundaryMinMax.X_Max = RootBoundaryNode;
                    BoundaryMinMax.X_Min = RootBoundaryNode;
                    BoundaryMinMax.Y_Max = RootBoundaryNode;
                    BoundaryMinMax.Y_Min = RootBoundaryNode;

                    // set the start node and move to the next one
                    // because we use the first for init
                    BoundaryNode tmpNode = RootBoundaryNode;
                    tmpNode = tmpNode.NextNode;

                    while (true)
                    {

                        // update the boundary max/min
                        UpdateBoundaryMaxMin(tmpNode);

                        // move to the next node
                        tmpNode = tmpNode.NextNode;

                        // break if we are in the start
                        if (tmpNode.IsTheRoot)
                            break;
                    }
                }
            }

            // create a face base on the  3 vertex
            Face newFace = new Face(he1);

            // add the face to the tree
            faceTree.Add(newFace);
        }
Exemplo n.º 9
0
        private void DrawFace( Face fe )
        {
            Half_Edge he = fe.HalfEnd;

            if (false && (he.TwinEdge == null || he.NextEdge.TwinEdge == null || he.NextEdge.NextEdge.TwinEdge == null))
            {
                // start the figure
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink_Color.BeginFigure(point, FigureBegin.Hollow);
                he = he.NextEdge;

                // add the first edge
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink_Color.AddLine(point);
                he = he.NextEdge;

                // add the sec edge
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink_Color.AddLine(point);

                // close the face
                meshGeo_Sink_Color.EndFigure(FigureEnd.Closed);

            }
            else
            {
                // start the figure
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink.BeginFigure(point, FigureBegin.Hollow);
                he = he.NextEdge;

                // add the first edge
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink.AddLine(point);
                he = he.NextEdge;

                // add the sec edge
                point.X = he.StartVertex.X;
                point.Y = he.StartVertex.Y;
                meshGeo_Sink.AddLine(point);

                // close the face
                meshGeo_Sink.EndFigure(FigureEnd.Closed);
            }

            if ( ShowVertex ) {
                DrawVertex( he.StartVertex );
                DrawVertex( he.NextEdge.StartVertex );
                DrawVertex( he.NextEdge.NextEdge.StartVertex );
            }
        }
Exemplo n.º 10
0
 /// <summary>
 /// Remove external face
 /// </summary>
 /// <param name="face"></param>
 public void RemoveFace( Face face )
 {
     // add the external face
     faceTree.Remove( face );
 }
Exemplo n.º 11
0
        /// <summary>
        /// Add vertex to data struct.
        /// </summary>
        /// <param name="vert"></param>
        public void AddVertex(IVertex<float> vert)
        {
            // find the face to attach
            Face selectFace = faceTree.FindFace(vert);

            // check if we find a triangle
            if (selectFace != null)
            {

                // disable the add base on select faces
            #if true
                Half_Edge minEdge;
                double minDist = selectFace.minDistEdge(vert, out minEdge);
                // check how close we are in the edges

                if (minDist > 0.1)
                {

                    #region split the face to 3 faces

                    //  get the he of the prev face
                    Half_Edge he1 = selectFace.HalfEnd;
                    Half_Edge he2 = selectFace.HalfEnd.NextEdge;
                    Half_Edge he3 = selectFace.HalfEnd.NextEdge.NextEdge;

                    // remove the old face
                    faceTree.Remove(selectFace);

                    // ------------------------------------------------------------------------------ //
                    // create the first triangle
                    Half_Edge he_a1, he_a2;
                    Half_Edge.CreateTriangle(he1, he2.StartVertex, vert, out he_a1, out he_a2);

                    // ------------------------------------------------------------------------------ //
                    // create the sec triangle
                    Half_Edge he_b1, he_b2;
                    Half_Edge.CreateTriangle(he2, he3.StartVertex, vert, out he_b1, out he_b2);

                    // ------------------------------------------------------------------------------ //
                    // create the third triangle
                    Half_Edge he_c1, he_c2;
                    Half_Edge.CreateTriangle(he3, he1.StartVertex, vert, out he_c1, out he_c2);

                    // ------------------------------------------------------------------------------ //

                    // link he twin edge
                    he_a1.TwinEdge = he_b2;
                    he_b2.TwinEdge = he_a1;

                    he_a2.TwinEdge = he_c1;
                    he_c1.TwinEdge = he_a2;

                    he_b1.TwinEdge = he_c2;
                    he_c2.TwinEdge = he_b1;

                    // create 3 new faces
                    Face fa1 = new Face(he1);
                    Face fa2 = new Face(he2);
                    Face fa3 = new Face(he3);

                    // add the new faces to the tree
                    faceTree.Add(fa1);
                    faceTree.Add(fa2);
                    faceTree.Add(fa3);

                    // test for edge swap
                    he_a2.DelaunayCorrection(he1.TwinEdge, faceTree);
                    he_b2.DelaunayCorrection(he2.TwinEdge, faceTree);
                    he_c2.DelaunayCorrection(he3.TwinEdge, faceTree);

                    #endregion

                }
                else
                {
            #if false
                    #region split the face to 4 faces

                    Console.WriteLine( "Find minDist:" + minDist.ToString() );

                    // calc the dist from the vert
                    double dx = minEdge.StartVertex.X - vert.X;
                    double dy = minEdge.StartVertex.Y - vert.Y;

                    double dist1 = Math.Sqrt( dx * dx + dy * dy );

                    dx = minEdge.NextEdge.StartVertex.X - vert.X;
                    dy = minEdge.NextEdge.StartVertex.Y - vert.Y;

                    double dist2 = Math.Sqrt( dx * dx + dy * dy );

                    Console.WriteLine( "vert1 dist :" + dist1.ToString() );
                    Console.WriteLine( "vert2 dist :" + dist2.ToString() );

                    #endregion
            #endif
                }

            #endif

            }
            else
            {
                //Console.WriteLine("Out of Boundary ");

                #region add new triangle to the Boundary

                // start the node from the start
                BoundaryNode tmpNode = RootBoundaryNode;
                int count = 0;

                BoundaryNode firstNode = null, lastNode = null;
                Boolean foundTheFirst = false, firstMatchIsRoot = false;
                Boolean TooClose = false;

                #region Forward Test
                // pass all the nodes and find the first and the last one that we can use
                while (true)
                {
                    Half_Edge he = tmpNode.currentEdge;

                    if ((vert.X - he.StartVertex.X) * (vert.X - he.StartVertex.X) + (vert.Y - he.StartVertex.Y) * (vert.Y - he.StartVertex.Y) < 0.1)
                    {

                        TooClose = true;
                        break;
                    }

                    // test the angle if is negative
                    // (neg mean that we are outside from the mesh )
                    if (Half_Edge.SideTest(he.StartVertex, he.NextEdge.StartVertex, vert))
                    {
                        count++;
                        if (foundTheFirst)
                        {
                            lastNode = tmpNode;
                        }
                        else
                        {
                            // set the first node
                            firstNode = tmpNode;

                            // set the last node
                            lastNode = tmpNode;

                            // set the flag that we have find the first
                            foundTheFirst = true;

                            if (tmpNode.IsTheRoot)
                                firstMatchIsRoot = true;
                        }
                    }
                    else if (foundTheFirst)
                        break;

                    // go to the next node
                    tmpNode = tmpNode.NextNode;

                    // check that we are in the beginning
                    if (tmpNode.IsTheRoot)
                        break;

                }
                #endregion

                if (firstNode == null)
                    return;

                if (TooClose)
                    return;

                #region Backward Test
                // reset the variables
                tmpNode = RootBoundaryNode.PrevNode;

                // pass all the nodes and find the first and the last one that we can use
                if (firstMatchIsRoot)
                    while (true)
                    {
                        Half_Edge he = tmpNode.currentEdge;

                        if ((vert.X - he.StartVertex.X) * (vert.X - he.StartVertex.X) + (vert.Y - he.StartVertex.Y) * (vert.Y - he.StartVertex.Y) < 0.1)
                        {

                            TooClose = true;
                            break;
                        }

                        // test the angle if is negative
                        // (neg mean that we are outside from the mesh )
                        if (Half_Edge.SideTest(he.StartVertex, he.NextEdge.StartVertex, vert))
                        {
                            count++;
                            // set the first node
                            firstNode = tmpNode;
                        }
                        else
                            break;

                        // go to the next node
                        tmpNode = tmpNode.PrevNode;

                        // check that we are in the beginning
                        if (tmpNode.IsTheRoot)
                            break;

                    }
                #endregion

                if (TooClose)
                    return;

                #region Link the new nodes

                // pass the nodes from the first to last
                tmpNode = firstNode;
                foundTheFirst = false;
                int count2 = 0;
                BoundaryNode endNode = lastNode.NextNode;
                while (tmpNode != endNode)
                {
                    Half_Edge he = tmpNode.currentEdge;
                    count2++;
                    Half_Edge he1, he2, he3;

                    // create the triangle
                    Half_Edge.CreateTriangle(he.StartVertex, vert, he.NextEdge.StartVertex,
                                              out he1, out he2, out he3);

                    // link the twin edge
                    he.TwinEdge = he3;
                    he3.TwinEdge = he;

                    // if we are in the mid of the search
                    // link the prev edge to the triangle
                    if (foundTheFirst)
                    {

                        // link the twin edges
                        he1.TwinEdge = tmpNode.PrevNode.currentEdge;
                        tmpNode.PrevNode.currentEdge.TwinEdge = he1;

                        // check if we are going to remove the root node
                        if (tmpNode.PrevNode.IsTheRoot)
                        {
                            // change the root node
                            tmpNode.PrevNode.PrevNode.IsTheRoot = true;
                            RootBoundaryNode = tmpNode.PrevNode.PrevNode;
                        }

                        // remove the prev one
                        tmpNode.PrevNode.Remove();

                        // replace the current edge with this one
                        tmpNode.currentEdge = he2;

                        // update the boundary node
                        UpdateBoundaryMaxMin(tmpNode);
                    }
                    else
                    {

                        // replace the board node with the 2 news
                        tmpNode.currentEdge = he1;

                        // update the boundary size
                        UpdateBoundaryMaxMin(tmpNode);

                        // add a new one after the one that we are now
                        tmpNode.InsertNode(new BoundaryNode(he2), true);

                        // move to the next one
                        tmpNode = tmpNode.NextNode;

                        //update the new node
                        UpdateBoundaryMaxMin(tmpNode);

                        // set that we have find the first that is correct
                        foundTheFirst = true;
                    }

                    Face newFace = new Face(he1);

                    // add the triangle to the list
                    faceTree.Add(newFace);

                    // fix the triangulation
                    newFace.HalfEnd.NextEdge.DelaunayCorrection(newFace.HalfEnd.NextEdge.NextEdge.TwinEdge, faceTree);

                    // move one to the list
                    tmpNode = tmpNode.NextNode;
                }

                #endregion

                #endregion

            }
        }
Exemplo n.º 12
0
 /// <summary>
 /// Add external face
 /// </summary>
 /// <param name="face"></param>
 public void AddFace( Face face )
 {
     // add the external face
     faceTree.Add( face );
 }
Exemplo n.º 13
0
        private void FaceTreeRemove(FaceDistTreeNode faceNode, Face newFace)
        {
            // check if we are in leaf
            if (faceNode.isLeaf)
            {

                // just remove the face from the list
                faceNode.FaceList.Remove(newFace);

            }
            else
            {
                Boolean isRemoved = false;

                // continue to the correct side
                if (newFace.Min_X > faceNode.X_mid)
                {
                    if (newFace.Min_Y > faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.UpRight, newFace);
                        isRemoved = true;
                    }
                    else if (newFace.Max_Y < faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.DownRight, newFace);
                        isRemoved = true;
                    }
                }
                else if (newFace.Max_X < faceNode.X_mid)
                {
                    if (newFace.Min_Y > faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.UpLeft, newFace);
                        isRemoved = true;
                    }
                    else if (newFace.Max_Y < faceNode.Y_mid)
                    {
                        FaceTreeRemove(faceNode.DownLeft, newFace);
                        isRemoved = true;
                    }
                }

                if (!isRemoved)
                {
                    // just remove the face from the list
                    faceNode.FaceList.Remove(newFace);
                }
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// update all the internal structs base on the specific struct
        /// </summary>
        public void Update( Face face )
        {
            // update all the internal face
            face.Update();

            /// update the position in the tree

            // find the face in the tree
        }