// // Use point-slope form to determine if the given point is on the line // public bool PointLiesOnAndBetweenEndpoints(Point thatPoint) { if (thatPoint == null) { return(false); } return(Segment.Between(thatPoint, Point1, Point2)); }
// // Creates a flying shape using a CROSSING intersection // offCross // | // ______|______ <--crossingInter // | // _____|_____ <--standsInter // // Returns <offCross> // public Point CreatesFlyingShapeWithCrossing(Intersection thatInter) { // A valid transversal is required for this shape if (!this.CreatesAValidTransversalWith(thatInter)) { return(null); } // We hould not have have endpoint standing as that is handled elsewhere if (this.StandsOnEndpoint() || thatInter.StandsOnEndpoint()) { return(null); } // // Determine which is the crossing intersection and which stands on the endpoints // Intersection crossingInter = null; Intersection standsInter = null; if (this.Crossing() && thatInter.StandsOn()) { crossingInter = this; standsInter = thatInter; } else if (thatInter.Crossing() && this.StandsOn()) { crossingInter = thatInter; standsInter = this; } else { return(null); } Segment transversal = this.AcquireTransversal(thatInter); // Stands on intersection must have BOTH points not on the transversal line // | // ______|______ // | // |_____ // | // | if (!transversal.PointLiesOn(standsInter.CreatesTShape())) { return(null); } // Success, we have the desired shape // Acquire return point: offCross Segment transversalCrossing = crossingInter.GetCollinearSegment(transversal); return(Segment.Between(crossingInter.intersect, transversalCrossing.Point1, standsInter.intersect) ? transversalCrossing.Point1 : transversalCrossing.Point2); }
public void AddCollinearPoint(Point newPt) { // Traverse list to find where to insert the new point in the list in the proper order for (int p = 0; p < points.Count - 1; p++) { if (Segment.Between(newPt, points[p], points[p + 1])) { points.Insert(p + 1, newPt); return; } } points.Add(newPt); }
public bool PointLiesOnAndExactlyBetweenEndpoints(Point thatPoint) { if (thatPoint == null) { return(false); } if (this.HasPoint(thatPoint)) { return(false); } return(Segment.Between(thatPoint, Point1, Point2)); }
// // Creates a shape like an extended t // offCross offCross // | | // _____|____ ______|______ // | | // |_____ offStands offStands _____| // // Returns <offStands, offCross> public KeyValuePair <Point, Point> CreatesCrossedTShape(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); } // // Determine which is the crossing intersection and which stands on the endpoints // Intersection crossingInter = null; Intersection standsInter = null; if (this.Crossing() && thatInter.StandsOnEndpoint()) { crossingInter = this; standsInter = thatInter; } else if (thatInter.Crossing() && this.StandsOnEndpoint()) { crossingInter = thatInter; standsInter = this; } else { return(nullPair); } // // Acquire the returning points // Segment transversal = this.AcquireTransversal(thatInter); Segment parallelStands = standsInter.OtherSegment(transversal); Point offStands = transversal.PointLiesOn(parallelStands.Point1) ? parallelStands.Point2 : parallelStands.Point1; Segment transversalCross = crossingInter.GetCollinearSegment(transversal); Point offCross = Segment.Between(crossingInter.intersect, transversalCross.Point1, standsInter.intersect) ? transversalCross.Point1 : transversalCross.Point2; return(new KeyValuePair <Point, Point>(offStands, offCross)); }
// // Angle measure (in degrees) between two vectors in standard position. // public static double AngleBetween(Point thisPoint, Point thatPoint) { Point origin = new Point("", 0, 0); if (Segment.Between(origin, thisPoint, thatPoint)) { return(180); } if (Segment.Between(thisPoint, origin, thatPoint)) { return(0); } if (Segment.Between(thatPoint, origin, thisPoint)) { return(0); } return(new Angle(thisPoint, origin, thatPoint).measure); }
// // Is this point in the interior of the angle? // public bool IsOnInterior(Point pt) { // | // | // x |_____ // Is the point on either ray such that it is outside the angle? (x in the image above) if (ray1.PointLiesOn(pt)) { // Point between the endpoints of the ray. if (Segment.Between(pt, GetVertex(), ray1.OtherPoint(GetVertex()))) { return(true); } // Point is on the ray, but extended in the right direction. return(Segment.Between(ray1.OtherPoint(GetVertex()), GetVertex(), pt)); } if (ray2.PointLiesOn(pt)) { // Point between the endpoints of the ray. if (Segment.Between(pt, GetVertex(), ray2.OtherPoint(GetVertex()))) { return(true); } // Point is on the ray, but extended in the right direction. return(Segment.Between(ray2.OtherPoint(GetVertex()), GetVertex(), pt)); } Angle newAngle1 = new Angle(A, GetVertex(), pt); Angle newAngle2 = new Angle(C, GetVertex(), pt); // This is an angle addition scenario, BUT not with these two angles; that is, one is contained in the other. if (Utilities.CompareValues(newAngle1.measure + newAngle2.measure, this.measure)) { return(true); } return(newAngle1.measure + newAngle2.measure <= this.measure); }
// // PointA // | // | X (pt) // |_____________________ otherSegment // | // | // PointB // public Point SameSidePoint(Segment otherSegment, Point pt) { // Is the given point on other? If so, we cannot make a determination. if (otherSegment.PointLiesOn(pt)) { return(null); } // Make a vector out of this vector as well as the vector connecting one of the points to the given pt Vector thisVector = new Vector(Point1, Point2); Vector thatVector = new Vector(Point1, pt); Vector projectionOfOtherOntoThis = thisVector.Projection(thatVector); // We are interested most in the endpoint of the projection (which is not the Point projectedEndpoint = projectionOfOtherOntoThis.NonOriginEndpoint(); // Find the intersection between the two lines Point intersection = FindIntersection(otherSegment); if (this.PointLiesOn(projectedEndpoint)) { System.Diagnostics.Debug.WriteLine("Unexpected: Projection does not lie on this line. " + this + " " + projectedEndpoint); } // The endpoint of the projection is on this vector. Therefore, we can judge which side of the given segment the given pt lies on. if (Segment.Between(projectedEndpoint, Point1, intersection)) { return(Point1); } if (Segment.Between(projectedEndpoint, Point2, intersection)) { return(Point2); } return(null); }
// // Acquires one or two intercepted arcs from an exterior or interior angle vertex. // public static KeyValuePair <Arc, Arc> GetInterceptedArcs(Circle circle, Angle angle) { KeyValuePair <Arc, Arc> nullPair = new KeyValuePair <Arc, Arc>(null, null); // // Get the intersection points of the rays of the angle. // Point interRay11 = null; Point interRay12 = null; circle.FindIntersection(angle.ray1, out interRay11, out interRay12); if (!angle.ray1.PointLiesOnAndBetweenEndpoints(interRay11)) { interRay11 = null; } if (!angle.ray1.PointLiesOnAndBetweenEndpoints(interRay12)) { interRay12 = null; } if (interRay11 == null && interRay12 != null) { interRay11 = interRay12; } // non-intersection if (interRay11 == null && interRay12 == null) { return(nullPair); } Point interRay21 = null; Point interRay22 = null; circle.FindIntersection(angle.ray2, out interRay21, out interRay22); if (!angle.ray2.PointLiesOnAndBetweenEndpoints(interRay21)) { interRay21 = null; } if (!angle.ray2.PointLiesOnAndBetweenEndpoints(interRay22)) { interRay22 = null; } if (interRay21 == null && interRay22 != null) { interRay21 = interRay22; } // non-intersection if (interRay21 == null && interRay22 == null) { return(nullPair); } // // Split the rays into cases based on if they are secants or not. // bool isSecRay1 = angle.ray1.IsSecant(circle); bool isSecRay2 = angle.ray2.IsSecant(circle); // // One Arc: No secants // if (!isSecRay1 && !isSecRay2) { // This means the endpoints of the ray were on the circle directly for each. return(new KeyValuePair <Arc, Arc>(Arc.GetFigureMinorArc(circle, interRay11, interRay21), null)); } // // One Arc; with one secant and one not. // else if (!isSecRay1 || !isSecRay2) { Segment secant = null; Segment nonSecant = null; Point endPtNonSecant = null; if (isSecRay1) { secant = angle.ray1; nonSecant = angle.ray2; endPtNonSecant = interRay21; } else { secant = angle.ray2; nonSecant = angle.ray1; endPtNonSecant = interRay11; } Segment chordOfSecant = circle.ContainsChord(secant); Point endptSecant = Segment.Between(chordOfSecant.Point1, angle.GetVertex(), chordOfSecant.Point2) ? chordOfSecant.Point1 : chordOfSecant.Point2; return(new KeyValuePair <Arc, Arc>(Arc.GetFigureMinorArc(circle, endPtNonSecant, endptSecant), null)); } // // Two arcs // else { // // Ensure proper ordering of points // Point closeRay1, farRay1; Point closeRay2, farRay2; if (Segment.Between(interRay11, angle.GetVertex(), interRay12)) { closeRay1 = interRay11; farRay1 = interRay12; } else { closeRay1 = interRay12; farRay1 = interRay11; } if (Segment.Between(interRay21, angle.GetVertex(), interRay22)) { closeRay2 = interRay21; farRay2 = interRay22; } else { closeRay2 = interRay22; farRay2 = interRay21; } return(new KeyValuePair <Arc, Arc>(Arc.GetFigureMinorArc(circle, closeRay1, closeRay2), Arc.GetFigureMinorArc(circle, farRay1, farRay2))); } }
public static Quadrilateral GenerateQuadrilateral(Segment s1, Segment s2, Segment s3, Segment s4) { // ____ // | // |____ // Check a C shape of 3 segments; the 4th needs to be opposite Segment top; Segment bottom; Segment left = AcquireMiddleSegment(s1, s2, s3, out top, out bottom); // Check C for the top, bottom, and right sides if (left == null) { return(null); } Segment right = s4; Segment tempOut1, tempOut2; Segment rightMid = AcquireMiddleSegment(top, bottom, right, out tempOut1, out tempOut2); // The middle segment we acquired must match the 4th segment if (!right.StructurallyEquals(rightMid)) { return(null); } // // The top / bottom cannot cross; bowtie or hourglass shape // A valid quadrilateral will have the intersections outside of the quad, that is defined // by the order of the three points: intersection and two endpts of the side // Point intersection = top.FindIntersection(bottom); // Check for parallel lines, then in-betweenness if (intersection != null && !double.IsNaN(intersection.X) && !double.IsNaN(intersection.Y)) { if (Segment.Between(intersection, top.Point1, top.Point2)) { return(null); } if (Segment.Between(intersection, bottom.Point1, bottom.Point2)) { return(null); } } // The left / right cannot cross; bowtie or hourglass shape intersection = left.FindIntersection(right); // Check for parallel lines, then in-betweenness if (intersection != null && !double.IsNaN(intersection.X) && !double.IsNaN(intersection.Y)) { if (Segment.Between(intersection, left.Point1, left.Point2)) { return(null); } if (Segment.Between(intersection, right.Point1, right.Point2)) { return(null); } } // // Verify that we have 4 unique points; And not different shapes (like a star, or triangle with another segment) // List <Point> pts = new List <Point>(); pts.Add(left.SharedVertex(top)); pts.Add(left.SharedVertex(bottom)); pts.Add(right.SharedVertex(bottom)); pts.Add(right.SharedVertex(top)); for (int i = 0; i < pts.Count - 1; i++) { for (int j = i + 1; j < pts.Count; j++) { if (pts[i].StructurallyEquals(pts[j])) { return(null); } } } return(new Quadrilateral(left, right, top, bottom)); }
// // Assumes our points represent vectors in std position // public static bool OppositeVectors(Point first, Point second) { Point origin = new Point("", 0, 0); return(Segment.Between(origin, first, second)); }
// 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)); }
// // 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)); }