Ejemplo n.º 1
0
        /// <summary>
        /// For a Point, last used Edge and possible Edges, retrieve the best next Edge
        /// </summary>
        /// <param name="point">The current Point</param>
        /// <param name="lastEdge">The last used Edge</param>
        /// <param name="possibleEdges">The possible next Edges</param>
        /// <returns>Best next Edge</returns>
        internal static PolygonEdge BestEdge(PolygonPoint point, PolygonEdge lastEdge, List <PolygonEdge> possibleEdges)
        {
            // If just Starting, return the first possible Edge of the Point
            // If only one possibility, return that
            if ((lastEdge.PointOne == null && lastEdge.PointTwo == null) || possibleEdges.Count == 1)
            {
                return(possibleEdges[0]);
            }

            // Variables needed to determine the next Edge
            var bestEdge  = possibleEdges[0];
            var bestAngle = (float)Math.PI * 2;
            // Vector from last Point to current Point
            var lastVector = (lastEdge.PointTwo.Point - lastEdge.PointOne.Point);

            lastVector.Normalize();
            // Using CCW Point Order, so the left Vector always points towards the Polygon Center
            var insideVector = new Point(-lastVector.Y, lastVector.X);

            // Check all possible Edges
            foreach (var possibleEdge in possibleEdges)
            {
                // Next Edge Vector
                var edgeVector = (possibleEdge.PointTwo.Point - possibleEdge.PointOne.Point);
                edgeVector.Normalize();
                // Dot determines if the Vector also points towards the Polygon Center or not (> 0, yes, < 0, no)
                var dot = insideVector.X * edgeVector.X + insideVector.Y * edgeVector.Y;
                // Cos represents the Angle between the last Edge and the next Edge
                var cos   = lastVector.X * edgeVector.X + lastVector.Y * edgeVector.Y;
                var angle = 0f;
                // Depending on the Dot-Value, calculate the actual "inner" Angle
                if ((insideVector.X * edgeVector.X + insideVector.Y * edgeVector.Y) > 0)
                {
                    angle = (float)Math.PI - (float)Math.Acos(cos);
                }
                else
                {
                    angle = (float)Math.PI + (float)Math.Acos(cos);
                }
                // Replace the old Values if a better Edge was found
                if (angle < bestAngle)
                {
                    bestAngle = angle;
                    bestEdge  = possibleEdge;
                }
            }
            return(bestEdge);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Searches the nearest StatusHelperElement from the given Point
        /// </summary>
        /// <param name="point">The Point to search a StatusHelperElement for</param>
        /// <returns>The nearest StatusHelperElement that is positioned left of the Poin</returns>
        internal StatusHelperElement SearchLeft(PolygonPoint point)
        {
            // The found StatusHelperElement and the Distance Variables
            StatusHelperElement result = null;
            var dist = Double.PositiveInfinity;

            // Search for the right StatusHelperElement
            foreach (var she in this.EdgesHelpers)
            {
                // Calculate the x-Coordinate of the Intersection between
                // a horizontal Line from the Point to the Left and the Edge of the StatusHelperElement
                Double xValue = Double.NaN;
                if (point.Y == she.Edge.PointOne.Y)
                {
                    xValue = she.Edge.PointOne.X;
                }
                else if (point.Y == she.Edge.PointTwo.Y)
                {
                    xValue = she.Edge.PointTwo.X;
                }
                else
                {
                    xValue = she.Edge.PointOne.X + ((point.Y - she.Edge.PointOne.Y) / (she.Edge.PointTwo.Y - she.Edge.PointOne.Y)) * (she.Edge.PointTwo.X - she.Edge.PointOne.X);
                }

                // If the xValue is smaller than or equal to the Point's x-Coordinate
                // (i.e. it lies on the left Side of it - allows a small Error)
                if (xValue <= (point.X + SweepLinePolygonTriangulator.Epsilon))
                {
                    // Calculate the Distance
                    var sheDist = point.X - xValue;

                    // Update, if the Distance is smaller than a previously found Result
                    if (sheDist < dist)
                    {
                        dist   = sheDist;
                        result = she;
                    }
                }
            }

            // Return the nearest found StatusHelperElement
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Searches the nearest StatusHelperElement from the given Point
        /// </summary>
        /// <param name="point">The Point to search a StatusHelperElement for</param>
        /// <returns>The nearest StatusHelperElement that is positioned left of the Poin</returns>
        internal StatusHelperElement SearchLeft(PolygonPoint point)
        {
            // The found StatusHelperElement and the Distance Variables
            StatusHelperElement result = null;
            var dist = Double.PositiveInfinity;

            var px = point.X;
            var py = point.Y;

            // Search for the right StatusHelperElement
            foreach (var she in this.EdgesHelpers)
            {
                // No need to calculate the X-Value
                if (she.MinX > px)
                {
                    continue;
                }

                // Calculate the x-Coordinate of the Intersection between
                // a horizontal Line from the Point to the Left and the Edge of the StatusHelperElement
                var xValue = she.Edge.PointOne.X + (py - she.Edge.PointOne.Y) * she.Factor;

                // If the xValue is smaller than or equal to the Point's x-Coordinate
                // (i.e. it lies on the left Side of it - allows a small Error)
                if (xValue <= (px + SweepLinePolygonTriangulator.Epsilon))
                {
                    // Calculate the Distance
                    var sheDist = px - xValue;

                    // Update, if the Distance is smaller than a previously found Result
                    if (sheDist < dist)
                    {
                        dist   = sheDist;
                        result = she;
                    }
                }
            }

            // Return the nearest found StatusHelperElement
            return(result);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Constructor that takes both Points of the Edge
 /// </summary>
 /// <param name="one">The Startpoint</param>
 /// <param name="two">The Endpoint</param>
 internal PolygonEdge(PolygonPoint one, PolygonPoint two)
 {
     this.mPointOne = one;
     this.mPointTwo = two;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Constructor taking an Edge and a Helper
 /// </summary>
 /// <param name="edge">The Edge of the StatusHelperElement</param>
 /// <param name="point">The Helper for the Edge of the StatusHelperElement</param>
 internal StatusHelperElement(PolygonEdge edge, PolygonPoint point)
 {
     this.Edge   = edge;
     this.Helper = point;
 }