예제 #1
0
        //
        // 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));
        }
예제 #2
0
        //
        // 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);
        }
예제 #3
0
 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);
 }
예제 #4
0
        public bool PointLiesOnAndExactlyBetweenEndpoints(Point thatPoint)
        {
            if (thatPoint == null)
            {
                return(false);
            }

            if (this.HasPoint(thatPoint))
            {
                return(false);
            }

            return(Segment.Between(thatPoint, Point1, Point2));
        }
예제 #5
0
        //
        // 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));
        }
예제 #6
0
파일: Point.cs 프로젝트: wcatykid/GeoShader
        //
        // 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);
        }
예제 #7
0
        //
        // 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);
        }
예제 #8
0
        //
        //     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);
        }
예제 #9
0
파일: Arc.cs 프로젝트: wcatykid/GeoShader
        //
        // 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)));
            }
        }
예제 #10
0
        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));
        }
예제 #11
0
파일: Point.cs 프로젝트: wcatykid/GeoShader
        //
        // 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));
        }
예제 #12
0
        //                   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));
        }
예제 #13
0
        //
        // 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));
        }