// Does this angle lie between the two lines? This is mainly for a parallelism check public bool OnInteriorOf(Intersection inter1, Intersection inter2) { Intersection angleBelongs = null; Intersection angleDoesNotBelong = null; // Determine the intersection to which the angle belongs if (inter1.InducesNonStraightAngle(this)) { angleBelongs = inter1; angleDoesNotBelong = inter2; } else if (inter2.InducesNonStraightAngle(this)) { angleBelongs = inter2; angleDoesNotBelong = inter1; } if (angleBelongs == null || angleDoesNotBelong == null) { return(false); } // Make the transversal out of the points of intersection Segment transversal = new Segment(angleBelongs.intersect, angleDoesNotBelong.intersect); Segment angleRayOnTraversal = this.ray1.IsCollinearWith(transversal) ? ray1 : ray2; // Is the endpoint of the angle (on the transversal) between the two intersection points? // Or, is that same endpoint on the far end beyond the other line: the other intersection point lies between the other points return(Segment.Between(angleRayOnTraversal.OtherPoint(this.GetVertex()), angleBelongs.intersect, angleDoesNotBelong.intersect) || Segment.Between(angleDoesNotBelong.intersect, angleBelongs.intersect, angleRayOnTraversal.OtherPoint(this.GetVertex()))); }
public static void MakeTriangles(Segment side, int length, int angle, out List <Triangle> tris) { tris = new List <Triangle>(); // 1 Segment newSide1 = side.ConstructSegmentByAngle(side.Point1, angle, length); Point newPoint1 = newSide1.OtherPoint(side.Point1); tris.Add(new Triangle(side.Point1, side.Point2, newPoint1)); // 2 Segment newSide2 = side.ConstructSegmentByAngle(side.Point2, angle, length); Point newPoint2 = newSide2.OtherPoint(side.Point2); tris.Add(new Triangle(side.Point1, side.Point2, newPoint2)); // 3 Point oppNewPoint1 = side.GetReflectionPoint(newPoint1); tris.Add(new Triangle(side.Point1, side.Point2, oppNewPoint1)); // 4 Point oppNewPoint2 = side.GetReflectionPoint(newPoint1); tris.Add(new Triangle(side.Point1, side.Point2, oppNewPoint2)); }
// // Do these segments overlay this angle? // public bool IsIncludedAngle(Segment seg1, Segment seg2) { // Do not allow the same segment. if (seg1.StructurallyEquals(seg2)) { return(false); } // Check direct inclusion if (seg1.Equals(ray1) && seg2.Equals(ray2) || seg1.Equals(ray2) && seg2.Equals(ray1)) { return(true); } // Check overlaying angle Point shared = seg1.SharedVertex(seg2); if (shared == null) { return(false); } Angle thatAngle = new Angle(seg1.OtherPoint(shared), shared, seg2.OtherPoint(shared)); return(this.Equates(thatAngle)); }
// // Creates a Leaner-Shape (a bench you can sit on) // // top // |______ tipStands // | // tipEndpt ______| // // Returns <tipEndpoint, tipStands> public KeyValuePair <Point, Point> CreatesLeanerShape(Intersection thatInter) { KeyValuePair <Point, Point> nullPair = new KeyValuePair <Point, Point>(null, null); // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(nullPair); } if (this.StandsOnEndpoint() && thatInter.StandsOnEndpoint()) { return(nullPair); } // // Determine which is the stands and which is the endpoint // Intersection endpointInter = null; Intersection standsInter = null; if (this.StandsOnEndpoint() && thatInter.StandsOn()) { endpointInter = this; standsInter = thatInter; } else if (thatInter.StandsOnEndpoint() && this.StandsOn()) { endpointInter = thatInter; standsInter = this; } else { return(nullPair); } // // Acquire Points // Point tipStands = standsInter.CreatesTShape(); Segment transversal = this.AcquireTransversal(thatInter); Segment parallelEndpoint = endpointInter.OtherSegment(transversal); Point tipEndpoint = parallelEndpoint.OtherPoint(endpointInter.intersect); // Determine sides Segment crossingTester = new Segment(tipEndpoint, tipStands); Point intersection = transversal.FindIntersection(crossingTester); // F-Shape if (!transversal.PointLiesOnAndBetweenEndpoints(intersection)) { return(nullPair); } // Desired Leaner shape return(new KeyValuePair <Point, Point>(tipEndpoint, tipStands)); }
// Corresponding angles if: // offRightEnd // standsOn (o) o e // o e standsOnEndpoint (e) // offLeftEnd eeeoeeeeeeee // o // o // // Returns <offLeftEnd, offRightEnd> // public KeyValuePair <Point, Point> CreatesSimpleTShape(Intersection thatInter) { KeyValuePair <Point, Point> nullPair = new KeyValuePair <Point, Point>(null, null); // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(nullPair); } if (this.StandsOnEndpoint() && thatInter.StandsOnEndpoint()) { return(nullPair); } // // Determine which is the crossing intersection and which stands on the endpoints // Intersection endpointInter = null; Intersection standsInter = null; if (this.StandsOnEndpoint() && thatInter.StandsOn()) { endpointInter = this; standsInter = thatInter; } else if (thatInter.Crossing() && this.StandsOnEndpoint()) { endpointInter = thatInter; standsInter = this; } else { return(nullPair); } // // Determine if the endpoint intersection extends beyond the stands parallel line // Segment transversal = this.AcquireTransversal(thatInter); Segment transversalEndpoint = endpointInter.GetCollinearSegment(transversal); if (transversal.PointLiesOnAndBetweenEndpoints(transversalEndpoint.Point1) && transversal.PointLiesOnAndBetweenEndpoints(transversalEndpoint.Point2)) { return(nullPair); } // // Acquire the returning points // Segment parallelEndpoint = endpointInter.OtherSegment(transversal); Point offLeftEnd = transversalEndpoint.OtherPoint(endpointInter.intersect); Point offRightEnd = parallelEndpoint.OtherPoint(endpointInter.intersect); return(new KeyValuePair <Point, Point>(offLeftEnd, offRightEnd)); }
private static Polygon ActuallyConstructThePolygonObject(List <Segment> orderedSides) { // // Check for lines that are actually collinear (and can be compressed into a single segment). // bool change = true; while (change) { change = false; for (int s = 0; s < orderedSides.Count; s++) { Segment first = orderedSides[s]; Segment second = orderedSides[(s + 1) % orderedSides.Count]; Point shared = first.SharedVertex(second); // We know these lines share an endpoint and that they are collinear. if (first.IsCollinearWith(second)) { Segment newSegment = new Segment(first.OtherPoint(shared), second.OtherPoint(shared)); // Replace the two original lines with the new line. orderedSides.Insert(s, newSegment); orderedSides.Remove(first); orderedSides.Remove(second); change = true; } } } KeyValuePair <List <Point>, List <Angle> > pair = MakePointsAngle(orderedSides); // If the polygon is concave, make that object. if (IsConcavePolygon(pair.Key)) { return(new ConcavePolygon(orderedSides, pair.Key, pair.Value)); } // Otherwise, make the other polygons switch (orderedSides.Count) { case 3: return(new Triangle(orderedSides)); case 4: return(Quadrilateral.GenerateQuadrilateral(orderedSides)); default: return(new Polygon(orderedSides, pair.Key, pair.Value)); } //return null; }
public static void MakeRightTriangles(Segment side, int length, out List <RightTriangle> tris) { tris = new List <RightTriangle>(); // // 1 // Segment perp = side.GetPerpendicularByLength(side.Point1, length); tris.Add(new RightTriangle(new Triangle(side.Point1, side.Point2, perp.OtherPoint(side.Point1)))); // 2 Segment oppPerp = perp.GetOppositeSegment(side.Point1); tris.Add(new RightTriangle(new Triangle(side.Point1, side.Point2, oppPerp.OtherPoint(side.Point1)))); // 3 perp = side.GetPerpendicularByLength(side.Point2, length); tris.Add(new RightTriangle(new Triangle(side.Point1, side.Point2, perp.OtherPoint(side.Point2)))); // 4 oppPerp = perp.GetOppositeSegment(side.Point2); tris.Add(new RightTriangle(new Triangle(side.Point1, side.Point2, oppPerp.OtherPoint(side.Point2)))); }
// // o // eoooooooo offStands // e //offEndpoint eeeeeee // o // Returns: <offEndpoint, offStands> public KeyValuePair <Point, Point> CreatesSimpleSShape(Intersection thatInter) { KeyValuePair <Point, Point> nullPair = new KeyValuePair <Point, Point>(null, null); // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(nullPair); } // Restrict to desired combination if (this.StandsOnEndpoint() && thatInter.StandsOnEndpoint()) { return(nullPair); } // // Determine which is the stands and which is the endpoint // Intersection endpointInter = null; Intersection standsInter = null; if (this.StandsOnEndpoint() && thatInter.StandsOn()) { endpointInter = this; standsInter = thatInter; } else if (thatInter.StandsOnEndpoint() && this.StandsOn()) { endpointInter = this; standsInter = thatInter; } else { return(nullPair); } // Determine S shape Point offStands = standsInter.CreatesTShape(); Segment transversal = this.AcquireTransversal(thatInter); Segment parallelEndpoint = endpointInter.OtherSegment(transversal); Point offEndpoint = parallelEndpoint.OtherPoint(endpointInter.intersect); Segment crossingTester = new Segment(offStands, offEndpoint); Point intersection = transversal.FindIntersection(crossingTester); return(transversal.PointLiesOnAndBetweenEndpoints(intersection) ? new KeyValuePair <Point, Point>(offEndpoint, offStands) : nullPair); }
public Angle(Segment ray1, Segment ray2) : base() { Point vertex = ray1.SharedVertex(ray2); if (vertex == null) throw new ArgumentException("Rays do not share a vertex: " + ray1 + " " + ray2); this.A = ray1.OtherPoint(vertex); this.B = vertex; this.C = ray2.OtherPoint(vertex); this.ray1 = ray1; this.ray2 = ray2; this.measure = toDegrees(findAngle(A, B, C)); if (measure <= 0) { //System.Diagnostics.Debug.WriteLine("NO-OP"); // throw new ArgumentException("Measure of " + this.ToString() + " is ZERO"); } }
public Angle(Segment ray1, Segment ray2) : base() { Point vertex = ray1.SharedVertex(ray2); if (vertex == null) { throw new ArgumentException("Rays do not share a vertex: " + ray1 + " " + ray2); } this.A = ray1.OtherPoint(vertex); this.B = vertex; this.C = ray2.OtherPoint(vertex); this.ray1 = ray1; this.ray2 = ray2; this.measure = toDegrees(findAngle(A, B, C)); if (measure <= 0) { //System.Diagnostics.Debug.WriteLine("NO-OP"); // throw new ArgumentException("Measure of " + this.ToString() + " is ZERO"); } }
public static void MakeRectangles(Segment side, double length, out Rectangle rect1, out Rectangle rect2) { // // First rectangle // Segment adj1 = side.GetPerpendicularByLength(side.Point1, length); Segment adj2 = side.GetPerpendicularByLength(side.Point2, length); Segment oppSide = new Segment(adj1.OtherPoint(side.Point1), adj2.OtherPoint(side.Point2)); rect1 = new Rectangle(side, oppSide, adj1, adj2); // // Second rectangle // Segment otherAdj1 = adj1.GetOppositeSegment(side.Point1); Segment otherAdj2 = adj2.GetOppositeSegment(side.Point2); oppSide = new Segment(otherAdj1.OtherPoint(side.Point1), otherAdj2.OtherPoint(side.Point2)); rect2 = new Rectangle(side, oppSide, otherAdj1, otherAdj2); }
// Parallel arrays of (1) vertices and (2) segments that share that given vertex. public static Polygon ConstructPolygon(List <Point> vertices, List <KeyValuePair <Segment, Segment> > pairs) { List <Segment> orderedSides = new List <Segment>(); // Follow the trail of sides starting at one of the first sides Segment currentSide = pairs[0].Key; orderedSides.Add(currentSide); Point currentVertex = currentSide.Point1; for (int v = 1; v < vertices.Count; v++) { // Where is the current vertex located? int nextVertexIndex = vertices.IndexOf(currentVertex); // Find the next side to follow. if (pairs[nextVertexIndex].Key.StructurallyEquals(currentSide)) { currentSide = pairs[nextVertexIndex].Value; } else { currentSide = pairs[nextVertexIndex].Key; } orderedSides.Add(currentSide); // Find the next vertex (moving along the next side) currentVertex = currentSide.OtherPoint(currentVertex); } if (orderedSides.Count != vertices.Count) { throw new Exception("Construction of new polygon failed."); } return(ActuallyConstructThePolygonObject(orderedSides)); }
// Does the given segment overlay this segment; we are looking at both as a RAY only. // We assume both rays share the same start vertex public bool RayOverlays(Segment thatRay) { if (this.Equals(thatRay)) { return(true); } if (!this.IsCollinearWith(thatRay)) { return(false); } // Do they share a vertex? Point shared = this.SharedVertex(thatRay); if (shared == null) { return(false); } Point thatOtherPoint = thatRay.OtherPoint(shared); Point thisOtherPoint = this.OtherPoint(shared); // Is thatRay smaller than the this ray if (Between(thatOtherPoint, shared, thisOtherPoint)) { return(true); } // Or if that Ray extends this Ray if (Between(thisOtherPoint, shared, thatOtherPoint)) { return(true); } return(false); }
// // Determine if the segment passes through the circle (we know it is not a chord since they have been filtered). // private bool IsSecant(Segment segment, List<Point> figPoints, out Segment chord) { // Make it null and overwrite when necessary. chord = null; // Is the segment exterior to the circle, but intersects at an endpoint (and wasn't tangent). if (this.PointIsExterior(segment.Point1) && this.PointLiesOn(segment.Point2)) return false; if (this.PointIsExterior(segment.Point2) && this.PointLiesOn(segment.Point1)) return false; // Is one endpoint of the segment simply on the interior of the circle (so we have nothing)? if (this.PointIsInterior(segment.Point1) || this.PointIsInterior(segment.Point2)) return false; if (ContainsDiameter(segment)) { chord = ConstructChord(segment, this.center, this.radius, figPoints); // Add radii to the list. radii.Add(new Segment(this.center, chord.Point1)); radii.Add(new Segment(this.center, chord.Point2)); return true; } // Acquire the line perpendicular to the segment that passes through the center of the circle. Segment perpendicular = segment.GetPerpendicular(this.center); // Is this perpendicular segment a radius? If so, it's tangent, not a secant //if (Utilities.CompareValues(perpendicular.Length, this.radius)) return false; // Is the perpendicular a radius? Check if the intersection of the segment and the perpendicular is on the circle. If so, it's tangent Point intersection = segment.FindIntersection(perpendicular); if (this.PointLiesOn(intersection)) return false; //Adjust perpendicular segment to include intersection with segment perpendicular = new Segment(intersection, this.center); // Filter the fact that there are no intersections if (perpendicular.Length > this.radius) return false; // 1/2 chord length // _____ circPoint // | / // | / // perp.Length | / radius // | / // |/ // Determine the half-chord length via Pyhtagorean Theorem. double halfChordLength = Math.Sqrt(Math.Pow(this.radius, 2) - Math.Pow(perpendicular.Length, 2)); chord = ConstructChord(segment, perpendicular.OtherPoint(this.center), halfChordLength, figPoints); return true; }
// // Is this a direct radius segment where one endpoint originates at the origin and extends outward? // Return the exact radius. private Segment IsRadius(Segment segment, List<Point> figPoints) { // The segment must originate from the circle center. if (!segment.HasPoint(this.center)) return null; // The segment must be at least as long as a radius. if (!Utilities.CompareValues(segment.Length, this.radius)) return null; Point nonCenterPt = segment.OtherPoint(this.center); // Check for a direct radius. if (this.PointLiesOn(nonCenterPt)) return segment; // // Check for an extended segment. // // radius // center _____ circPt // // Find the exact coordinates of the 'circ' points. // Point inter1 = null; Point inter2 = null; this.FindIntersection(segment, out inter1, out inter2); Point figPoint = Utilities.GetStructurally<Point>(figPoints, inter1); if (figPoint == null) figPoint = Utilities.GetStructurally<Point>(figPoints, inter2); return new Segment(center, figPoint); }
// Does the given segment overlay this segment; we are looking at both as a RAY only. // We assume both rays share the same start vertex public bool RayOverlays(Segment thatRay) { if (this.Equals(thatRay)) return true; if (!this.IsCollinearWith(thatRay)) return false; // Do they share a vertex? Point shared = this.SharedVertex(thatRay); if (shared == null) return false; Point thatOtherPoint = thatRay.OtherPoint(shared); Point thisOtherPoint = this.OtherPoint(shared); // Is thatRay smaller than the this ray if (Between(thatOtherPoint, shared, thisOtherPoint)) return true; // Or if that Ray extends this Ray if (Between(thisOtherPoint, shared, thatOtherPoint)) return true; return false; }
// // Do these segments overlay this angle? // public bool IsIncludedAngle(Segment seg1, Segment seg2) { // Do not allow the same segment. if (seg1.StructurallyEquals(seg2)) return false; // Check direct inclusion if (seg1.Equals(ray1) && seg2.Equals(ray2) || seg1.Equals(ray2) && seg2.Equals(ray1)) return true; // Check overlaying angle Point shared = seg1.SharedVertex(seg2); if (shared == null) return false; Angle thatAngle = new Angle(seg1.OtherPoint(shared), shared, seg2.OtherPoint(shared)); return this.Equates(thatAngle); }
// top // o // offStands oooooooe // e //offEndpoint eeeeeee // o // bottom // Returns: <offEndpoint, offStands> public KeyValuePair <Point, Point> CreatesSimplePIShape(Intersection thatInter) { KeyValuePair <Point, Point> nullPair = new KeyValuePair <Point, Point>(null, null); // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(nullPair); } // Restrict to desired combination if (this.StandsOnEndpoint() && thatInter.StandsOnEndpoint()) { return(nullPair); } // // Determine which is the stands and which is the endpoint // Intersection endpointInter = null; Intersection standsInter = null; if (this.StandsOnEndpoint() && thatInter.StandsOn()) { endpointInter = this; standsInter = thatInter; } else if (thatInter.StandsOnEndpoint() && this.StandsOn()) { endpointInter = this; standsInter = thatInter; } else { return(nullPair); } // // Avoid Some shapes // Segment transversal = this.AcquireTransversal(thatInter); Segment transversalStands = standsInter.GetCollinearSegment(transversal); Point top = null; Point bottom = null; if (Segment.Between(standsInter.intersect, transversalStands.Point1, endpointInter.intersect)) { top = transversalStands.Point1; bottom = transversalStands.Point2; } else { top = transversalStands.Point2; bottom = transversalStands.Point1; } // Avoid: ____ Although this shouldn't happen since both intersections do not stand on endpoints // ____| // // Also avoid Simple F-Shape // if (transversal.HasPoint(top) || transversal.HasPoint(bottom)) { return(nullPair); } // Determine S shape Point offStands = standsInter.CreatesTShape(); Segment parallelEndpoint = endpointInter.OtherSegment(transversal); Point offEndpoint = parallelEndpoint.OtherPoint(endpointInter.intersect); Segment crossingTester = new Segment(offStands, offEndpoint); Point intersection = transversal.FindIntersection(crossingTester); // S-shape // PI-Shape return(transversal.PointLiesOnAndBetweenEndpoints(intersection) ? nullPair : new KeyValuePair <Point, Point>(offEndpoint, offStands)); }