// // Creates a basic S-Shape with standsOnEndpoints // // ______ offThat // | // offThis ______| // // Return <offThis, offThat> public KeyValuePair <Point, Point> CreatesBasicSShape(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()) { return(nullPair); } if (!thatInter.StandsOnEndpoint()) { return(nullPair); } // // Determine offThis and offThat // Segment transversal = this.AcquireTransversal(thatInter); Segment parallelThis = this.OtherSegment(transversal); Segment parallelThat = thatInter.OtherSegment(transversal); Point offThis = transversal.PointLiesOnAndBetweenEndpoints(parallelThis.Point1) ? parallelThis.Point2 : parallelThis.Point1; Point offThat = transversal.PointLiesOnAndBetweenEndpoints(parallelThat.Point1) ? parallelThat.Point2 : parallelThat.Point1; // Avoid C-like scenario Segment crossingTester = new Segment(offThis, offThat); Point intersection = transversal.FindIntersection(crossingTester); // C-shape if (!transversal.PointLiesOnAndBetweenEndpoints(intersection)) { return(nullPair); } // S-Shape return(new KeyValuePair <Point, Point>(offThis, offThat)); }
public static ConcreteAST.Point AcquireRestrictedPoint(List <ConcreteAST.Point> points, ConcreteAST.Point that, ConcreteAST.Segment seg, ConcreteAST.Arc arc) { ConcreteAST.Point pt = AcquirePoint(points, that); if (pt == null) { return(null); } return(!seg.PointLiesOnAndBetweenEndpoints(pt) || !arc.PointLiesOn(pt) ? null : pt); }
// // Point must be in the given circle and then, specifically in the specified angle // public override bool PointLiesInside(Point pt) { // Is the point in the sector's circle? if (!theArc.theCircle.PointLiesInside(pt)) { return(false); } // Radii if (radius1.PointLiesOnAndBetweenEndpoints(pt)) { return(false); } if (radius2.PointLiesOnAndBetweenEndpoints(pt)) { return(false); } // // For the Minor Arc, create two angles. // The sum must equal the measure of the angle created by the endpoints. // double originalMinorMeasure = theArc.minorMeasure; double centralAngle1 = new Angle(theArc.endpoint1, theArc.theCircle.center, pt).measure; double centralAngle2 = new Angle(theArc.endpoint2, theArc.theCircle.center, pt).measure; bool isInMinorArc = Utilities.CompareValues(theArc.minorMeasure, centralAngle1 + centralAngle2); if (theArc is MinorArc) { return(isInMinorArc); } if (theArc is MajorArc) { return(!isInMinorArc); } if (theArc is Semicircle) { Semicircle semi = theArc as Semicircle; // The point in question must lie on the same side of the diameter as the middle point Segment candSeg = new Segment(pt, semi.middlePoint); Point intersection = semi.diameter.FindIntersection(candSeg); return(!candSeg.PointLiesOnAndBetweenEndpoints(intersection)); } return(false); }
public override void FindIntersection(Segment that, out Point inter1, out Point inter2) { inter1 = FindIntersection(that); inter2 = null; if (!this.PointLiesOnAndBetweenEndpoints(inter1)) { inter1 = null; } if (!that.PointLiesOnAndBetweenEndpoints(inter1)) { inter1 = null; } }
// Simple function for creating a point (if needed since it is not labeled by the UI). private Point HandleIntersectionPoint(List <Point> containment, List <Point> toAdd, GeometryTutorLib.ConcreteAST.Segment segment, Point pt) { if (pt == null) { return(null); } // The point must be between the endpoints of the segment if (!segment.PointLiesOnAndBetweenEndpoints(pt)) { return(null); } return(HandleIntersectionPoint(containment, toAdd, pt)); }
// // 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); }
// // Is thatSegment a bisector of this segment in terms of the coordinatization from the UI? // public Point CoordinateBisector(Segment thatSegment) { // Do these segments intersect within both sets of stated endpoints? Point intersection = this.FindIntersection(thatSegment); if (!this.PointLiesOnAndExactlyBetweenEndpoints(intersection)) { return(null); } if (!thatSegment.PointLiesOnAndBetweenEndpoints(intersection)) { return(null); } // Do they intersect in the middle of this segment return(Utilities.CompareValues(Point.calcDistance(this.Point1, intersection), Point.calcDistance(this.Point2, intersection)) ? intersection : null); }
// // Point is on the perimeter? // public override bool PointLiesOn(Point pt) { if (pt == null) { return(false); } // Radii KeyValuePair <Segment, Segment> radii = theArc.GetRadii(); if (radii.Key.PointLiesOnAndBetweenEndpoints(pt) || radii.Value.PointLiesOnAndBetweenEndpoints(pt)) { return(true); } // This point must lie on the circle in question, minimally. if (!theArc.theCircle.PointLiesOn(pt)) { return(false); } // Arc if (theArc is MajorArc) { return(Arc.BetweenMajor(pt, theArc as MajorArc)); } else if (theArc is MinorArc) { return(Arc.BetweenMinor(pt, theArc as MinorArc)); } else if (theArc is Semicircle) { Semicircle semi = theArc as Semicircle; // The point in question must lie on the same side of the diameter as the middle point Segment candSeg = new Segment(pt, semi.middlePoint); Point intersection = semi.diameter.FindIntersection(candSeg); return(!candSeg.PointLiesOnAndBetweenEndpoints(intersection)); } return(false); }
private void Verify() { if (points.Count < 2) { throw new ArgumentException("A Collinear relationship requires at least 2 points: " + this.ToString()); } // Create a segment of the endpoints to compare all points for collinearity Segment line = new Segment(points[0], points[points.Count - 1]); foreach (Point pt in points) { if (!line.PointLiesOn(pt)) { throw new ArgumentException("Point " + pt + " is not collinear with line " + line.ToString()); } if (!line.PointLiesOnAndBetweenEndpoints(pt)) { throw new ArgumentException("Point " + pt + " is not between the endpoints of segment " + line.ToString()); } } }
public bool CoordinateAngleBisector(Segment thatSegment) { if (!thatSegment.PointLiesOnAndBetweenEndpoints(this.GetVertex())) { return(false); } if (thatSegment.IsCollinearWith(this.ray1) || thatSegment.IsCollinearWith(this.ray2)) { return(false); } Point interiorPoint = this.IsOnInteriorExplicitly(thatSegment.Point1) ? thatSegment.Point1 : thatSegment.Point2; if (!this.IsOnInteriorExplicitly(interiorPoint)) { return(false); } Angle angle1 = new Angle(A, GetVertex(), interiorPoint); Angle angle2 = new Angle(C, GetVertex(), interiorPoint); return(Utilities.CompareValues(angle1.measure, angle2.measure)); }
private void Verify() { if (points.Count < 2) throw new ArgumentException("A Collinear relationship requires at least 2 points: " + this.ToString()); // Create a segment of the endpoints to compare all points for collinearity Segment line = new Segment(points[0], points[points.Count - 1]); foreach (Point pt in points) { if (!line.PointLiesOn(pt)) { throw new ArgumentException("Point " + pt + " is not collinear with line " + line.ToString()); } if (!line.PointLiesOnAndBetweenEndpoints(pt)) { throw new ArgumentException("Point " + pt + " is not between the endpoints of segment " + line.ToString()); } } }
public bool HasSegment(Segment thatSegment) { return segment.HasSubSegment(thatSegment) && thatSegment.PointLiesOnAndBetweenEndpoints(intersect); }
public override void FindIntersection(Segment that, out Point inter1, out Point inter2) { inter1 = FindIntersection(that); inter2 = null; if (!this.PointLiesOnAndBetweenEndpoints(inter1)) inter1 = null; if (!that.PointLiesOnAndBetweenEndpoints(inter1)) inter1 = null; }
public override void FindIntersection(Segment that, out Point inter1, out Point inter2) { inter1 = null; inter2 = null; Point foundInter = null; List<Point> intersections = new List<Point>(); foreach (Segment side in orderedSides) { if (side.IsCollinearWith(that)) { if (that.PointLiesOnAndBetweenEndpoints(side.Point1)) Utilities.AddStructurallyUnique<Point>(intersections, side.Point1); if (that.PointLiesOnAndBetweenEndpoints(side.Point2)) Utilities.AddStructurallyUnique<Point>(intersections, side.Point2); if (side.PointLiesOnAndBetweenEndpoints(that.Point1)) Utilities.AddStructurallyUnique<Point>(intersections, that.Point1); if (side.PointLiesOnAndBetweenEndpoints(that.Point2)) Utilities.AddStructurallyUnique<Point>(intersections, that.Point2); } else { foundInter = side.FindIntersection(that); // Is the intersection in the middle of the segments? if (side.PointLiesOnAndBetweenEndpoints(foundInter) && that.PointLiesOnAndBetweenEndpoints(foundInter)) { // A segment may intersect a polygon through up to 2 vertices creating 4 intersections. if (!Utilities.HasStructurally<Point>(intersections, foundInter)) intersections.Add(foundInter); } } } if (!(this is ConcavePolygon) && intersections.Count > 2) { throw new Exception("A segment intersecting a polygon may have up to 2 intersection points, not: " + intersections.Count); } if (intersections.Any()) inter1 = intersections[0]; if (intersections.Count > 1) inter2 = intersections[1]; }
// // Creates a Chair // // | | | // |_____|____ leftInter |_________ tipOfT // | | | // | | | // off tipOfT // // bottomInter // // <leftInter, bottomInter> // Returns the legs of the chair in specific ordering: <off, bottomTip> public KeyValuePair <Point, Point> CreatesChairShape(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); } // Both intersections must be standing on (and not endpoints) if (!this.StandsOn() || !thatInter.StandsOn()) { return(nullPair); } if (this.StandsOnEndpoint() || thatInter.StandsOnEndpoint()) { return(nullPair); } Point thisTipOfT = this.CreatesTShape(); Point thatTipOfT = thatInter.CreatesTShape(); Segment transversal = this.AcquireTransversal(thatInter); Intersection leftInter = null; Intersection bottomInter = null; // Avoid: // | // |______ // | | // | | // this is leftInter Point bottomTip = null; if (transversal.PointLiesOn(thisTipOfT)) { if (transversal.PointLiesOnAndBetweenEndpoints(thisTipOfT)) { return(nullPair); } leftInter = this; bottomInter = thatInter; bottomTip = thisTipOfT; } // thatInter is leftInter else if (transversal.PointLiesOn(thatTipOfT)) { if (transversal.PointLiesOnAndBetweenEndpoints(thatTipOfT)) { return(nullPair); } leftInter = thatInter; bottomInter = this; bottomTip = thisTipOfT; } // Otherwise, this indicates a PI-shaped scenario else { return(nullPair); } // // Returns the bottom of the legs of the chair // Segment parallelLeft = leftInter.OtherSegment(transversal); Segment crossingTester = new Segment(parallelLeft.Point1, bottomTip); Point intersection = transversal.FindIntersection(crossingTester); Point off = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelLeft.Point2 : parallelLeft.Point1; return(new KeyValuePair <Point, Point>(off, bottomTip)); }
// // Is this segment perpendicular to the given segment in terms of the coordinatization from the UI? // public Point CoordinatePerpendicular(Segment thatSegment) { // // Do these segments intersect within both sets of stated endpoints? // Point intersection = this.FindIntersection(thatSegment); if (!this.PointLiesOnAndBetweenEndpoints(intersection)) return null; if (!thatSegment.PointLiesOnAndBetweenEndpoints(intersection)) return null; // // Special Case // if ((IsVertical() && thatSegment.IsHorizontal()) || (thatSegment.IsVertical() && IsHorizontal())) return intersection; // Does m1 * m2 = -1 (opposite reciprocal slopes) return Utilities.CompareValues(thatSegment.Slope * this.Slope, -1) ? intersection : null; }
// // Take the angle congruence and bisector and create the AngleBisector relation // \ // \ // B ---------V---------A // \ // \ // C // private static List<EdgeAggregator> InstantiateToDef(Point intersectionPoint, Intersection inter, CongruentSegments cs) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Does the given point of intersection apply to this actual intersection object if (!intersectionPoint.Equals(inter.intersect)) return newGrounded; // The entire segment AB Segment overallSegment = new Segment(cs.cs1.OtherPoint(intersectionPoint), cs.cs2.OtherPoint(intersectionPoint)); // The segment must align completely with one of the intersection segments Segment interCollinearSegment = inter.GetCollinearSegment(overallSegment); if (interCollinearSegment == null) return newGrounded; // Does this intersection have the entire segment AB if (!inter.HasSegment(overallSegment)) return newGrounded; Segment bisector = inter.OtherSegment(overallSegment); Segment bisectedSegment = inter.GetCollinearSegment(overallSegment); // Check if the bisected segment extends is the exact same segment as the overall segment AB if (!bisectedSegment.StructurallyEquals(overallSegment)) { if (overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point1) && overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point2)) return newGrounded; } SegmentBisector newSB = new SegmentBisector(inter, bisector); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(inter); antecedent.Add(cs); newGrounded.Add(new EdgeAggregator(antecedent, newSB, annotation)); return newGrounded; }
// // Construct the AngleBisector if we have // // V---------------A // / \ // / \ // / \ // B C // // Congruent(Angle, A, V, C), Angle(C, V, B)), Segment(V, C)) -> AngleBisector(Angle(A, V, B) // // private static List<EdgeAggregator> InstantiateToDef(CongruentAngles cas, Segment segment) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Find the shared segment between the two angles; we know it is valid if we reach this point Segment shared = cas.AreAdjacent(); // The bisector must align with the given segment if (!segment.IsCollinearWith(shared)) return newGrounded; // We need a true bisector in which the shared vertex of the angles in between the endpoints of this segment if (!segment.PointLiesOnAndBetweenEndpoints(cas.ca1.GetVertex())) return newGrounded; // // Create the overall angle which is being bisected // Point vertex = cas.ca1.GetVertex(); Segment newRay1 = cas.ca1.OtherRayEquates(shared); Segment newRay2 = cas.ca2.OtherRayEquates(shared); Angle combinedAngle = new Angle(newRay1.OtherPoint(vertex), vertex, newRay2.OtherPoint(vertex)); // Determine if the segment is a straight angle (we don't want an angle bisector here, we would want a segment bisector) if (newRay1.IsCollinearWith(newRay2)) return newGrounded; // The bisector cannot be of the form: // \ // \ // V---------------A // / // / // B if (!combinedAngle.IsOnInteriorExplicitly(segment.Point1) && !combinedAngle.IsOnInteriorExplicitly(segment.Point2)) return newGrounded; AngleBisector newAB = new AngleBisector(combinedAngle, segment); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(segment); antecedent.Add(cas); newGrounded.Add(new EdgeAggregator(antecedent, newAB, annotation)); return newGrounded; }
// // Creates a Topped F-Shape // top // offLeft __________ offEnd <--- Stands on // | // |_____ off <--- Stands on // | // | // bottom // // Returns: <bottom, off> public KeyValuePair <Intersection, Point> CreatesToppedFShape(Intersection thatInter) { KeyValuePair <Intersection, Point> nullPair = new KeyValuePair <Intersection, Point>(null, null); // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(nullPair); } // Avoid both standing on an endpoint OR crossing if (this.StandsOnEndpoint() || thatInter.StandsOnEndpoint()) { return(nullPair); } if (this.Crossing() || thatInter.Crossing()) { return(nullPair); } Segment transversal = this.AcquireTransversal(thatInter); Intersection standsOnTop = null; Intersection standsOnBottom = null; // Top has 2 points on the transversal; bottom has 3 Segment nonTransversalThis = this.OtherSegment(transversal); Segment nonTransversalThat = thatInter.OtherSegment(transversal); if (transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThis.Point1) || transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThis.Point2)) { // | // ____| <--- Stands on // | // |_____ off <--- Stands on // | // | if (transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThat.Point1) || transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThat.Point2)) { return(nullPair); } standsOnBottom = this; standsOnTop = thatInter; } else if (transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThat.Point1) || transversal.PointLiesOnAndBetweenEndpoints(nonTransversalThat.Point2)) { standsOnBottom = this; standsOnTop = thatInter; } else { return(nullPair); } // Check that the bottom extends the transversal if (!standsOnBottom.GetCollinearSegment(transversal).HasStrictSubSegment(transversal)) { return(nullPair); } Point off = standsOnBottom.OtherSegment(transversal).OtherPoint(standsOnBottom.intersect); return(new KeyValuePair <Intersection, Point>(standsOnBottom, off)); }
public bool HasSegment(Segment thatSegment) { return(segment.HasSubSegment(thatSegment) && thatSegment.PointLiesOnAndBetweenEndpoints(intersect)); }
// // Is this segment an altitude based on the coordinates (precomputation) // public bool CoordinateAltitude(Segment thatSegment) { // // Check to see if the altitude is actually one of the sides of the triangle // if (this.HasSegment(thatSegment) && this.isRight) { // Find the right angle; the altitude must be one of those segments if (Utilities.CompareValues(this.AngleA.measure, 90)) return AngleA.HasSegment(thatSegment); if (Utilities.CompareValues(this.AngleB.measure, 90)) return AngleB.HasSegment(thatSegment); if (Utilities.CompareValues(this.AngleC.measure, 90)) return AngleC.HasSegment(thatSegment); } // // Two sides must intersect the given segment at a single point // Point otherIntersection = null; Point thisIntersection = null; Segment oppSide = null; if (Segment.IntersectAtSamePoint(SegmentA, SegmentB, thatSegment)) { thisIntersection = SegmentA.FindIntersection(SegmentB); otherIntersection = SegmentC.FindIntersection(thatSegment); oppSide = SegmentC; } if (Segment.IntersectAtSamePoint(SegmentA, SegmentC, thatSegment)) { thisIntersection = SegmentA.FindIntersection(SegmentC); otherIntersection = SegmentB.FindIntersection(thatSegment); oppSide = SegmentB; } if (Segment.IntersectAtSamePoint(SegmentB, SegmentC, thatSegment)) { thisIntersection = SegmentB.FindIntersection(SegmentC); otherIntersection = SegmentA.FindIntersection(thatSegment); oppSide = SegmentA; } if (otherIntersection == null || oppSide == null) return false; // Avoid a dangling altitude: // // |\ // | \ // | \ // \ // Need to make sure 'this' and the the 'other' intersection is actually on the potential altitude segment if (!thatSegment.PointLiesOnAndBetweenEndpoints(thisIntersection)) return false; if (!thatSegment.PointLiesOnAndBetweenEndpoints(otherIntersection)) return false; // We require a perpendicular intersection return Utilities.CompareValues((new Angle(thisIntersection, otherIntersection, oppSide.Point1)).measure, 90); }
// // Point is on the perimeter? // public override bool PointLiesOn(Point pt) { if (pt == null) return false; // Radii KeyValuePair<Segment, Segment> radii = theArc.GetRadii(); if (radii.Key.PointLiesOnAndBetweenEndpoints(pt) || radii.Value.PointLiesOnAndBetweenEndpoints(pt)) return true; // This point must lie on the circle in question, minimally. if (!theArc.theCircle.PointLiesOn(pt)) return false; // Arc if (theArc is MajorArc) return Arc.BetweenMajor(pt, theArc as MajorArc); else if (theArc is MinorArc) return Arc.BetweenMinor(pt, theArc as MinorArc); else if (theArc is Semicircle) { Semicircle semi = theArc as Semicircle; // The point in question must lie on the same side of the diameter as the middle point Segment candSeg = new Segment(pt, semi.middlePoint); Point intersection = semi.diameter.FindIntersection(candSeg); return !candSeg.PointLiesOnAndBetweenEndpoints(intersection); } return false; }
// // Point must be in the given circle and then, specifically in the specified angle // public override bool PointLiesInside(Point pt) { // Is the point in the sector's circle? if (!theArc.theCircle.PointLiesInside(pt)) return false; // Radii if (radius1.PointLiesOnAndBetweenEndpoints(pt)) return false; if (radius2.PointLiesOnAndBetweenEndpoints(pt)) return false; // // For the Minor Arc, create two angles. // The sum must equal the measure of the angle created by the endpoints. // double originalMinorMeasure = theArc.minorMeasure; double centralAngle1 = new Angle(theArc.endpoint1, theArc.theCircle.center, pt).measure; double centralAngle2 = new Angle(theArc.endpoint2, theArc.theCircle.center, pt).measure; bool isInMinorArc = Utilities.CompareValues(theArc.minorMeasure, centralAngle1 + centralAngle2); if (theArc is MinorArc) return isInMinorArc; if (theArc is MajorArc) return !isInMinorArc; if (theArc is Semicircle) { Semicircle semi = theArc as Semicircle; // The point in question must lie on the same side of the diameter as the middle point Segment candSeg = new Segment(pt, semi.middlePoint); Point intersection = semi.diameter.FindIntersection(candSeg); return !candSeg.PointLiesOnAndBetweenEndpoints(intersection); } return false; }
// // Determine tangency of the given segment. // Indicate tangency by returning the segment which creates the 90^0 angle. // public Segment IsTangent(Segment segment) { // If the center and the segment points are collinear, this will not be a tangent. if (segment.PointLiesOn(this.center)) return null; // Acquire the line perpendicular to the segment that passes through the center of the circle. Segment perpendicular = segment.GetPerpendicular(this.center); // If the segment was found to pass through the center, it is not a tangent if (perpendicular.Equals(segment)) return null; // Is this perpendicular segment a radius? Check length //if (!Utilities.CompareValues(perpendicular.Length, this.radius)) return null; // Is the perpendicular a radius? Check that the intersection of the segment and the perpendicular is on the circle Point intersection = segment.FindIntersection(perpendicular); if (!this.PointLiesOn(intersection)) return null; // The intersection between the perpendicular and the segment must be within the endpoints of the segment. return segment.PointLiesOnAndBetweenEndpoints(intersection) ? perpendicular : null; }
// // Creates an F-Shape // top // _____ offEnd <--- Stands on Endpt // | // |_____ offStands <--- Stands on // | // | // bottom // Order of non-collinear points is order of intersections: <this, that> public KeyValuePair <Point, Point> CreatesFShape(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); } // Avoid both standing on an endpoint if (this.StandsOnEndpoint() && thatInter.StandsOnEndpoint()) { return(nullPair); } Intersection endpt = null; Intersection standsOn = null; if (this.StandsOnEndpoint() && thatInter.StandsOn()) { endpt = this; standsOn = thatInter; } else if (thatInter.StandsOnEndpoint() && this.StandsOn()) { endpt = thatInter; standsOn = this; } else { return(nullPair); } Segment transversal = this.AcquireTransversal(thatInter); Segment transversalStands = standsOn.GetCollinearSegment(transversal); // // Determine Top and bottom to avoid PI shape // Point top = null; Point bottom = null; if (Segment.Between(standsOn.intersect, transversalStands.Point1, endpt.intersect)) { bottom = transversalStands.Point1; top = transversalStands.Point2; } else { bottom = transversalStands.Point2; top = transversalStands.Point1; } // Avoid: ____ Although this shouldn't happen since both intersections do not stand on endpoints // ____| if (transversal.HasPoint(top) && transversal.HasPoint(bottom)) { return(nullPair); } // Also avoid Simple PI-Shape // if (!transversal.HasPoint(top) && !transversal.HasPoint(bottom)) { return(nullPair); } // Find the two points that make the points of the F Segment parallelEndPt = endpt.OtherSegment(transversal); Segment parallelStands = standsOn.OtherSegment(transversal); Point offEnd = transversal.PointLiesOn(parallelEndPt.Point1) ? parallelEndPt.Point2 : parallelEndPt.Point1; Point offStands = transversal.PointLiesOn(parallelStands.Point1) ? parallelStands.Point2 : parallelStands.Point1; // Check this is not a crazy F // _____ // | // ____| // | // | Point intersection = transversal.FindIntersection(new Segment(offEnd, offStands)); if (transversal.PointLiesOnAndBetweenEndpoints(intersection)) { return(nullPair); } // Return in the order of 'off' points: <this, that> return(this.Equals(endpt) ? new KeyValuePair <Point, Point>(offEnd, offStands) : new KeyValuePair <Point, Point>(offStands, offEnd)); }
// // Does the given segment pass through the circle so that it acts as a diameter (or contains a diameter)? // private bool ContainsDiameter(Segment segment) { if (!segment.PointLiesOnAndBetweenEndpoints(this.center)) return false; // the endpoints of the segment must be on or outside the circle. double distance = Point.calcDistance(this.center, segment.Point1); if (distance < this.radius) return false; distance = Point.calcDistance(this.center, segment.Point2); if (distance < this.radius) return false; return true; }
// // Is thatSegment a bisector of this segment in terms of the coordinatization from the UI? // public Point CoordinateBisector(Segment thatSegment) { // Do these segments intersect within both sets of stated endpoints? Point intersection = this.FindIntersection(thatSegment); if (!this.PointLiesOnAndExactlyBetweenEndpoints(intersection)) return null; if (!thatSegment.PointLiesOnAndBetweenEndpoints(intersection)) return null; // Do they intersect in the middle of this segment return Utilities.CompareValues(Point.calcDistance(this.Point1, intersection), Point.calcDistance(this.Point2, intersection)) ? intersection : null; }
public override void FindIntersection(Segment that, out Point inter1, out Point inter2) { // Find the points of intersection this.theCircle.FindIntersection(that, out inter1, out inter2); // The points must be on this minor arc. if (this is MinorArc) { if (!Arc.BetweenMinor(inter1, this)) inter1 = null; if (!Arc.BetweenMinor(inter2, this)) inter2 = null; } else if (this is MajorArc) { if (!Arc.BetweenMajor(inter1, this)) inter1 = null; if (!Arc.BetweenMajor(inter2, this)) inter2 = null; } else if (this is Semicircle) { if (!(this as Semicircle).PointLiesOn(inter1)) inter1 = null; if (!(this as Semicircle).PointLiesOn(inter2)) inter2 = null; } if (!that.PointLiesOnAndBetweenEndpoints(inter1)) inter1 = null; if (!that.PointLiesOnAndBetweenEndpoints(inter2)) inter2 = null; if (inter1 == null && inter2 != null) { inter1 = inter2; inter2 = null; } }
// 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)); }
public bool CoordinateMedian(Segment thatSegment) { // // Two sides must intersect the median at a single point // Point midptIntersection = null; Point coincidingIntersection = null; Segment oppSide = null; if (Segment.IntersectAtSamePoint(SegmentA, SegmentB, thatSegment)) { coincidingIntersection = SegmentA.FindIntersection(SegmentB); midptIntersection = SegmentC.FindIntersection(thatSegment); oppSide = SegmentC; } else if (Segment.IntersectAtSamePoint(SegmentA, SegmentC, thatSegment)) { coincidingIntersection = SegmentA.FindIntersection(SegmentC); midptIntersection = SegmentB.FindIntersection(thatSegment); oppSide = SegmentB; } else if (Segment.IntersectAtSamePoint(SegmentB, SegmentC, thatSegment)) { coincidingIntersection = SegmentB.FindIntersection(SegmentC); midptIntersection = SegmentA.FindIntersection(thatSegment); oppSide = SegmentA; } if (midptIntersection == null || oppSide == null) return false; // It is possible for the segment to be parallel to the opposite side; results in NaN. if (midptIntersection.X == double.NaN || midptIntersection.Y == double.NaN) return false; // The intersection must be on the potential median if (!thatSegment.PointLiesOnAndBetweenEndpoints(coincidingIntersection)) return false; // The midpoint intersection must be on the potential median if (!thatSegment.PointLiesOnAndBetweenEndpoints(midptIntersection)) return false; if (!Segment.Between(coincidingIntersection, thatSegment.Point1, thatSegment.Point2)) return false; if (!oppSide.PointLiesOnAndBetweenEndpoints(midptIntersection)) return false; // Midpoint of the remaining side needs to align return midptIntersection.Equals(oppSide.Midpoint()); }
public bool CoordinateAngleBisector(Segment thatSegment) { if (!thatSegment.PointLiesOnAndBetweenEndpoints(this.GetVertex())) return false; if (thatSegment.IsCollinearWith(this.ray1) || thatSegment.IsCollinearWith(this.ray2)) return false; Point interiorPoint = this.IsOnInteriorExplicitly(thatSegment.Point1) ? thatSegment.Point1 : thatSegment.Point2; if (!this.IsOnInteriorExplicitly(interiorPoint)) return false; Angle angle1 = new Angle(A, GetVertex(), interiorPoint); Angle angle2 = new Angle(C, GetVertex(), interiorPoint); return Utilities.CompareValues(angle1.measure, angle2.measure); }