// // 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); }
/// <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); }
// // 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); }