public Node( Edge edge )
 {
     m_Edge = edge;
     m_Plane = new Plane2( edge.Start, edge.End );
 }
        /// <summary>
        /// Classifies an edge w.r.t a plane, adding it to inFrontEdges or behindEdges. If the plane intersects the edge, it's split,
        /// and the two resulting edges are added to inFrontEdges or behindEdges instead
        /// </summary>
        private static void ClassifyEdge( Plane2 plane, Edge edge, ICollection< Edge > inFrontEdges, ICollection< Edge > behindEdges )
        {
            PlaneClassification startClass = plane.ClassifyPoint( edge.Start, OnPlaneTolerance );
            PlaneClassification endClass = plane.ClassifyPoint( edge.End, OnPlaneTolerance );

            if ( startClass == PlaneClassification.On )
            {
                startClass = endClass;
            }
            if ( endClass == PlaneClassification.On )
            {
                endClass = startClass;
            }
            if ( startClass == endClass )
            {
                //	Edge endpoints on the same side of the splitter plane - no split required
                if ( startClass == PlaneClassification.Behind )
                {
                    AddEdge( behindEdges, edge );
                }
                else if ( startClass == PlaneClassification.InFront )
                {
                    AddEdge( inFrontEdges, edge );
                }
                //	Don't care about edges that are on the splitter plane
                return;
            }
            Point2 midPt = Intersections2.GetLinePlaneIntersection( edge.Start, edge.End, plane ).IntersectionPosition;

            Edge startToMid = new Edge( edge.Start, midPt, edge.IsDoubleSided, edge.SourceEdge );
            Edge midToEnd = new Edge( midPt, edge.End, edge.IsDoubleSided, edge.SourceEdge );

            if ( startClass == PlaneClassification.Behind )
            {
                AddEdge( behindEdges, startToMid );
                AddEdge( inFrontEdges, midToEnd );
            }
            else
            {
                AddEdge( inFrontEdges, startToMid );
                AddEdge( behindEdges, midToEnd );
            }
        }
            /// <summary>
            /// Splits a source polygon along a plane, returning the sub-poly behind the plane in "behind"
            /// and the sub-poly in-front of the plane in "inFront"
            /// </summary>
            public void Split( Plane2 plane, Polygon source, out Polygon behind, out Polygon inFront )
            {
                float tolerance = 0.001f;
                int firstDefiniteClassIndex = -1;
                PlaneClassification[] classifications = new PlaneClassification[ source.Indices.Length ];
                for ( int index = 0; index < source.Indices.Length; ++index )
                {
                    classifications[ index ] = plane.ClassifyPoint( m_Points[ source.Indices[ index ] ], tolerance );
                    if ( ( firstDefiniteClassIndex == -1 ) && ( classifications[ index ] != PlaneClassification.On ) )
                    {
                        firstDefiniteClassIndex = index;
                    }
                }
                if ( firstDefiniteClassIndex > 1 )
                {
                    //	The first two points are on the split plane. This means that we
                    //	can easily classify the polygon as either behind or in front depending on the first
                    //	definite class
                    if ( classifications[ firstDefiniteClassIndex ] == PlaneClassification.Behind )
                    {
                        behind = new Polygon( source.Indices );
                        inFront = null;
                    }
                    else
                    {
                        behind = null;
                        inFront = new Polygon( source.Indices );
                    }
                    return;
                }

                int lastPtIndex = firstDefiniteClassIndex;
                int curPtIndex = ( lastPtIndex + 1 ) % source.Indices.Length;
                Point2 lastPt = m_Points[ source.Indices[ lastPtIndex ] ];
                PlaneClassification lastClass = classifications[ lastPtIndex ];

                List< int > behindPoints = new List< int >( source.Indices.Length + 2 );
                List< int > inFrontPoints = new List< int >( source.Indices.Length + 2 );

                for ( int count = 0; count < source.Indices.Length; ++count )
                {
                    Point2 curPt = m_Points[ source.Indices[ curPtIndex ] ];
                    PlaneClassification curClass = classifications[ curPtIndex ];
                    if ( curClass == PlaneClassification.On )
                    {
                        curClass = lastClass;
                    }

                    if ( curClass != lastClass )
                    {
                        //	Split line on plane
                        Line2Intersection intersection = Intersections2.GetLinePlaneIntersection( lastPt, curPt, plane );
                        int newPtIndex = AddPoint( intersection.IntersectionPosition );
                        behindPoints.Add( newPtIndex );
                        inFrontPoints.Add( newPtIndex );
                    }

                    if ( curClass == PlaneClassification.Behind )
                    {
                        behindPoints.Add( source.Indices[ curPtIndex ] );
                    }
                    else
                    {
                        inFrontPoints.Add( source.Indices[ curPtIndex ] );
                    }

                    lastClass = curClass;
                    lastPt = curPt;

                    curPtIndex = ( curPtIndex + 1 ) % source.Indices.Length;
                }

                behind = ( behindPoints.Count == 0 ) ? null : new Polygon( behindPoints.ToArray( ) );
                inFront = ( inFrontPoints.Count == 0 ) ? null : new Polygon( inFrontPoints.ToArray( ) );
            }
 /// <summary>
 /// Setup constructor
 /// </summary>
 /// <param name="p0">Start point of the edge</param>
 /// <param name="p1">End point of the edge</param>
 public Edge( Point2 p0, Point2 p1 )
 {
     m_P0 = p0;
     m_P1 = p1;
     m_Plane = new Plane2( p0, p1 );
 }
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="src">Source plane</param>
 public Plane2( Plane2 src )
 {
     m_Normal = src.m_Normal;
     m_Distance = src.m_Distance;
 }
 public Node( Point2 start, Point2 end )
 {
     m_Plane = new Plane2( start, end );
 }