예제 #1
0
    public void ReplaceWithSingleNode(BeachLineElement newNode)
    {
        if (Parent != null)
        {
            newNode.SetParent(Parent);
            if (Parent.LeftChild == this)
            {
                Parent.SetLeftChild(newNode);
            }
            else
            {
                Parent.SetRightChild(newNode);
            }
        }
        else
        {
            // This is the root node
            mBeachLine.SetRoot(newNode);
        }

        if (LeftChild != null)
        {
            newNode.SetLeftChild(LeftChild);
            LeftChild.SetParent(newNode);
        }
        if (RightChild != null)
        {
            newNode.SetRightChild(RightChild);
            RightChild.SetParent(newNode);
        }
        mParent     = null;
        mLeftChild  = null;
        mRightChild = null;
    }
예제 #2
0
    public void Split(BeachLineArc newArc)
    {
        float splitX    = newArc.Focus.x;
        float sweepLine = newArc.Focus.y;

        BeachLineArc newLeftArc    = new BeachLineArc(this);
        BeachLineArc newRightArc   = new BeachLineArc(this);
        Vector2      splitPoint    = new Vector2(splitX, y(splitX));
        Vector2      edgeDirection = Tangent(splitX);

        // Make edgeDirection always point in the positive x direction
        edgeDirection = edgeDirection.x < 0 ? -edgeDirection : edgeDirection;
        BeachLineEdge newLeftEdge  = new BeachLineEdge(splitPoint, -edgeDirection);
        BeachLineEdge newRightEdge = new BeachLineEdge(splitPoint, edgeDirection);

        newLeftEdge.SetLeftChild(newLeftArc);
        newLeftEdge.SetRightChild(newRightEdge);
        newLeftEdge.SetParent(Parent);
        newRightEdge.SetLeftChild(newArc);
        newRightEdge.SetRightChild(newRightArc);
        newRightEdge.SetParent(newLeftEdge);
        newLeftArc.SetParent(newLeftEdge);
        newRightArc.SetParent(newRightEdge);
        newArc.SetParent(newRightEdge);

        // Change next and prev links
        BeachLineEdge prevEdge = (BeachLineEdge)Prev;
        BeachLineEdge nextEdge = (BeachLineEdge)Next;

        LinkRemove();
        if (prevEdge != null)
        {
            prevEdge.LinkInsertAfter(newLeftArc);
        }
        else
        {
            // newLeftArc is going to be the new start of the list
            if (nextEdge != null)
            {
                newLeftArc.SetNext(nextEdge);
                nextEdge.SetPrev(newLeftArc);
            }
        }
        newLeftArc.LinkInsertAfter(newLeftEdge)
        .LinkInsertAfter(newArc)
        .LinkInsertAfter(newRightEdge)
        .LinkInsertAfter(newRightArc);
        //if (nextEdge != null)
        //{
        //    newRightArc.SetNext(nextEdge);
        //    nextEdge.SetPrev(newRightArc);
        //}

        BeachLineElement parent = Parent;

        if (parent == null)
        {
            // This is root. Replace this with left edge.
            BeachLineRoot.SetRoot(newLeftEdge);
        }
        else
        {
            // Set parent to point to new construct
            if (parent.LeftChild == this)
            {
                parent.SetLeftChild(newLeftEdge);
            }
            else if (parent.RightChild == this)
            {
                parent.SetRightChild(newLeftEdge);
            }
            else
            {
                Debug.LogError("Error in Split - couldn't find child in parent.");
            }
        }

        // We can now remove this node
        //SetLeftArc(null);
        //SetRightArc(null);
        //SetLeftEdge(null);
        //SetRightEdge(null);
        SetLeftChild(null);
        SetRightChild(null);
        SetParent(null);
    }
예제 #3
0
    public List <BeachLineEdge> Squeeze(out BeachLineEdge newEdge)
    {
        // These are the output edges
        BeachLineEdge leftEdge  = (BeachLineEdge)Prev;
        BeachLineEdge rightEdge = (BeachLineEdge)Next;
        BeachLineArc  leftArc   = (BeachLineArc)leftEdge.Prev;
        BeachLineArc  rightArc  = (BeachLineArc)rightEdge.Next;

        // Create new edge
        // To create it, we need the intersection point of the two output edges plus the
        // focuses of the two arcs.
        Vector2 intersection;

        leftEdge.CheckIntersection(rightEdge, out intersection);
        Vector2 focus1           = leftArc.Focus;
        Vector2 focus2           = rightArc.Focus;
        Vector2 perpendicular    = focus2 - focus1;
        Vector2 newEdgeDirection = new Vector2(perpendicular.y, -perpendicular.x);

        if (Vector2.Dot(leftEdge.Direction.normalized + rightEdge.Direction.normalized, -newEdgeDirection) > 0)
        //if (newEdgeDirection.y < 0)
        {
            newEdgeDirection = -newEdgeDirection;
        }

        newEdge = new BeachLineEdge(intersection, newEdgeDirection.normalized);


        BeachLineEdge edgeToReplace = leftEdge == Parent ? rightEdge : leftEdge;

        //newEdge.SetLeftArc(LeftArc);
        //newEdge.SetRightArc(RightArc);
        // Replace other edge with new edge
        edgeToReplace.ReplaceWithSingleNode(newEdge);

        // Replace parent with sibling

        BeachLineElement sibling = Sibling;

        sibling.SetParent(null);
        bool iAmLeftChild = this == Parent.LeftChild;

        if (iAmLeftChild)
        {
            Parent.SetRightChild(null);
        }
        else
        {
            Parent.SetLeftChild(null);
        }

        BeachLineElement parentsParent     = Parent.Parent;
        bool             parentIsLeftChild = Parent == parentsParent.LeftChild;

        if (parentIsLeftChild)
        {
            parentsParent.SetLeftChild(sibling);
        }
        else
        {
            parentsParent.SetRightChild(sibling);
        }
        sibling.SetParent(parentsParent);

        //Parent.ReplaceWith(Sibling);

        //Parent.SetLeftChild(null);
        //Parent.SetRightChild(null);

        // Set next/prev for altered nodes
        leftArc.SetNext(newEdge);
        newEdge.SetPrev(leftArc);
        newEdge.SetNext(rightArc);
        rightArc.SetPrev(newEdge);

        // Remove this node from tree
        SetParent(null);
        SetLeftChild(null);
        SetRightChild(null);
        SetNext(null);
        SetPrev(null);
        leftEdge.SetParent(null);
        leftEdge.SetLeftChild(null);
        leftEdge.SetRightChild(null);
        leftEdge.SetNext(null);
        leftEdge.SetPrev(null);
        rightEdge.SetParent(null);
        rightEdge.SetLeftChild(null);
        rightEdge.SetRightChild(null);
        rightEdge.SetNext(null);
        rightEdge.SetPrev(null);

        leftEdge.SetEndpoint(intersection);
        rightEdge.SetEndpoint(intersection);

        List <BeachLineEdge> outputList = new List <BeachLineEdge>
        {
            leftEdge,
            rightEdge
        };

        return(outputList);
    }