Example #1
0
        //
        // We want our first vector to be downward (-90 degrees std unit circle)
        //
        private Point GetFirstNeighbor(Point currentPt)
        {
            Point imaginaryPrevPt = new Point("", currentPt.X, currentPt.Y + 1);
            Point prevCurrVector  = Point.MakeVector(imaginaryPrevPt, currentPt);

            // We want the point that creates the smallest angle w.r.t. to the stdVector

            // Information that will change along with the current candidate next point.
            double currentAngle     = 360; // This will be overwritten
            Point  currentNextPoint = null;

            // Index of the current point so we can get its neighbors.
            int currentPtIndex = graph.IndexOf(currentPt);

            foreach (UndirectedPlanarGraph.PlanarGraphEdge edge in graph.nodes[currentPtIndex].edges)
            {
                int   neighborIndex = graph.IndexOf(edge.target);
                Point neighbor      = graph.nodes[neighborIndex].thePoint;

                // Create a vector of the current point with it's neighbor
                Point currentNeighborVector = Point.MakeVector(currentPt, neighbor);

                // Cross product of the two vectors to determine if we have an angle that is < 180 or > 180.
                double crossProduct = Point.CrossProduct(prevCurrVector, currentNeighborVector);

                double angleMeasure = Point.AngleBetween(prevCurrVector, currentNeighborVector);

                // if (GeometryTutorLib.Utilities.GreaterThan(crossProduct, 0)) angleMeasure = angleMeasure;
                if (GeometryTutorLib.Utilities.CompareValues(crossProduct, 0))
                {
                    angleMeasure = 180;
                }
                else if (crossProduct < 0)
                {
                    angleMeasure = 360 - angleMeasure;
                }

                // If there are have the same angle, choose the one farther away (it is due to two connections)
                // So these points are collinear with a segment, but indistinguishable with two arcs.
                if (Utilities.CompareValues(angleMeasure, currentAngle))
                {
                    double currentDist = Point.calcDistance(currentPt, currentNextPoint);
                    double candDist    = Point.calcDistance(currentPt, neighbor);

                    // Take the farthest point.
                    if (candDist > currentDist)
                    {
                        currentAngle     = angleMeasure;
                        currentNextPoint = neighbor;
                    }
                }
                else if (angleMeasure < currentAngle)
                {
                    currentAngle     = angleMeasure;
                    currentNextPoint = neighbor;
                }
            }

            return(currentNextPoint);
        }
Example #2
0
        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="pen">The pen.</param>
        /// <param name="p1">The first point.</param>
        /// <param name="p2">The second point.</param>
        public void DrawLine(Pen pen, Point p1, Point p2)
        {
            double angle     = p1.AngleBetween(p2);
            float  halfWidth = Math.Max(1, pen.Width / 2.0f);

            var size = this.ViewportSize;
            var quad = new Quad();

            quad.SetVertexLocations(
                p1.MoveAlongAngle(angle + 90, halfWidth).ToScreenCoordinates(size),
                p1.MoveAlongAngle(angle - 90, halfWidth).ToScreenCoordinates(size),
                p2.MoveAlongAngle(angle - 90, halfWidth).ToScreenCoordinates(size),
                p2.MoveAlongAngle(angle + 90, halfWidth).ToScreenCoordinates(size));

            quad.SetVertexUVs(new RectangleF(0, 0, 1, 1));

            this.CreateSprite(pen, quad);
        }
Example #3
0
        //
        // With respect to the given vector (based on prevPt and currentPt), return the tightest counter-clockwise neighbor.
        //
        private Point GetTightestCounterClockwiseNeighbor(Point prevPt, Point currentPt)
        {
            Point prevCurrVector = Point.MakeVector(prevPt, currentPt);

            // We want the point that creates the smallest angle w.r.t. to the stdVector

            // Information that will change along with the current candidate next point.
            double currentAngle     = 360; // This will be overwritten
            Point  currentNextPoint = null;

            // Index of the current point so we can get its neighbors.
            int prevPtIndex    = graph.IndexOf(prevPt);
            int currentPtIndex = graph.IndexOf(currentPt);

            foreach (UndirectedPlanarGraph.PlanarGraphEdge edge in graph.nodes[currentPtIndex].edges)
            {
                int neighborIndex = graph.IndexOf(edge.target);

                if (prevPtIndex != neighborIndex)
                {
                    Point neighbor = graph.nodes[neighborIndex].thePoint;

                    // Create a vector of the current point with it's neighbor
                    Point currentNeighborVector = Point.MakeVector(currentPt, neighbor);

                    // Cross product of the two vectors to determine if we have an angle that is < 180 or > 180.
                    double crossProduct = Point.CrossProduct(prevCurrVector, currentNeighborVector);

                    double angleMeasure = Point.AngleBetween(Point.GetOppositeVector(prevCurrVector), currentNeighborVector);

                    // if (GeometryTutorLib.Utilities.GreaterThan(crossProduct, 0)) angleMeasure = angleMeasure;
                    if (GeometryTutorLib.Utilities.CompareValues(crossProduct, 0))
                    {
                        // Circles create a legitimate situation where we want to walk back in the same 'collinear' path.
                        if (Point.OppositeVectors(prevCurrVector, currentNeighborVector))
                        {
                            throw new System.Exception("FacetCalculator has collinear points in graph, but a cycle in the edges.");
                        }
                        else
                        {
                            angleMeasure = 180;
                        }
                    }
                    else if (crossProduct < 0)
                    {
                        angleMeasure = 360 - angleMeasure;
                    }

                    // If there are have the same angle, choose the one farther away (it is due to two connections)
                    // So these points are collinear with a segment, but indistinguishable with two arcs.
                    if (Utilities.CompareValues(angleMeasure, currentAngle))
                    {
                        double currentDist = Point.calcDistance(currentPt, currentNextPoint);
                        double candDist    = Point.calcDistance(currentPt, neighbor);

                        // Take the farthest point.
                        if (candDist > currentDist)
                        {
                            currentAngle     = angleMeasure;
                            currentNextPoint = neighbor;
                        }
                    }
                    if (angleMeasure < currentAngle)
                    {
                        currentAngle     = angleMeasure;
                        currentNextPoint = neighbor;
                    }
                }
            }

            return(currentNextPoint);
        }