예제 #1
0
        // 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())));
        }
예제 #2
0
        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));
        }
예제 #3
0
        //
        // 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));
        }
예제 #4
0
        //
        // 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));
        }
예제 #5
0
        // 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));
        }
예제 #6
0
        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;
        }
예제 #7
0
        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))));
        }
예제 #8
0
        //
        //                    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);
        }
예제 #9
0
파일: Angle.cs 프로젝트: wcatykid/GeoShader
        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");
            }
        }
예제 #10
0
        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");
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
        // 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));
        }
예제 #13
0
        // 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);
        }
예제 #14
0
        //
        // 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;
        }
예제 #15
0
        //
        // 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);
        }
예제 #16
0
        // 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;
        }
예제 #17
0
파일: Angle.cs 프로젝트: wcatykid/GeoShader
        //
        // 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);
        }
예제 #18
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));
        }