コード例 #1
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //
        // 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));
        }
コード例 #2
0
ファイル: Utilities.cs プロジェクト: boubre/TutorAI
        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);
        }
コード例 #3
0
ファイル: Sector.cs プロジェクト: wcatykid/GeoShader
        //
        // 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);
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
        // 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));
        }
コード例 #6
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //
        //                    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);
        }
コード例 #7
0
        //
        // 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);
        }
コード例 #8
0
ファイル: Sector.cs プロジェクト: wcatykid/GeoShader
        //
        // 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);
        }
コード例 #9
0
        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());
                }
            }
        }
コード例 #10
0
        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));
        }
コード例 #11
0
ファイル: Collinear.cs プロジェクト: wcatykid/GeoShader
        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());
                }
            }
        }
コード例 #12
0
 public bool HasSegment(Segment thatSegment)
 {
     return segment.HasSubSegment(thatSegment) && thatSegment.PointLiesOnAndBetweenEndpoints(intersect);
 }
コード例 #13
0
ファイル: Segment.cs プロジェクト: wcatykid/GeoShader
        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;
        }
コード例 #14
0
ファイル: Polygon.cs プロジェクト: wcatykid/GeoShader
        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];
        }
コード例 #15
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //
        // 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));
        }
コード例 #16
0
ファイル: Segment.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #17
0
        //
        // 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;
        }
コード例 #18
0
        //
        // 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;
        }
コード例 #19
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //
        // 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));
        }
コード例 #20
0
 public bool HasSegment(Segment thatSegment)
 {
     return(segment.HasSubSegment(thatSegment) && thatSegment.PointLiesOnAndBetweenEndpoints(intersect));
 }
コード例 #21
0
ファイル: Triangle.cs プロジェクト: wcatykid/GeoShader
        //
        // 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);
        }
コード例 #22
0
ファイル: Sector.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #23
0
ファイル: Sector.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #24
0
ファイル: Circle.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #25
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //
        // 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));
        }
コード例 #26
0
ファイル: Circle.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #27
0
ファイル: Segment.cs プロジェクト: wcatykid/GeoShader
        //
        // 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;
        }
コード例 #28
0
ファイル: Arc.cs プロジェクト: wcatykid/GeoShader
        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;
            }
        }
コード例 #29
0
ファイル: Intersection.cs プロジェクト: wcatykid/GeoShader
        //                   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));
        }
コード例 #30
0
ファイル: Triangle.cs プロジェクト: wcatykid/GeoShader
        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());
        }
コード例 #31
0
ファイル: Angle.cs プロジェクト: wcatykid/GeoShader
        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);
        }