Beispiel #1
0
        //
        // Creates an S-Shape
        //
        //         |______
        //         |
        //   ______|
        //         |
        //
        //   Order of non-collinear points is order of intersections: <this, that>
        public KeyValuePair <Point, Point> CreatesStandardSShape(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);
            }

            Point thisNonCollinear = this.CreatesTShape();
            Point thatNonCollinear = thatInter.CreatesTShape();

            if (thisNonCollinear == null || thatNonCollinear == null)
            {
                return(nullPair);
            }

            //
            // Verify that the shape is PI and not an S-shape; look for the intersection point NOT between the endpoints of the transversal
            //
            // The transversal should be valid
            Segment transversal  = this.AcquireTransversal(thatInter);
            Point   intersection = transversal.FindIntersection(new Segment(thisNonCollinear, thatNonCollinear));

            // PI-shape
            if (!transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                return(nullPair);
            }

            // S-Shape
            return(new KeyValuePair <Point, Point>(thisNonCollinear, thatNonCollinear));
        }
        //Demonstrates: congruent chords have congruent arcs
        public Page306Theorem7_4_1(bool onoff, bool complete)
            : base(onoff, complete)
        {
            Point o = new Point("O", 0, 0); points.Add(o);
            Point r = new Point("R", -3, 4); points.Add(r);
            Point s = new Point("S", 2, Math.Sqrt(21)); points.Add(s);
            Point t = new Point("T", 2, -Math.Sqrt(21)); points.Add(t);
            Point u = new Point("U", -3, -4); points.Add(u);

            Segment rt = new Segment(r, t);
            Segment su = new Segment(s, u);
            Point v = rt.FindIntersection(su); points.Add(v);

            Segment rs = new Segment(r, s); segments.Add(rs);
            Segment ut = new Segment(u, t); segments.Add(ut);

            Circle c = new Circle(o, 5.0);
            circles.Add(c);

            parser = new LiveGeometry.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            given.Add(new GeometricCongruentSegments(rs, ut));

            MinorArc a1 = (MinorArc)parser.Get(new MinorArc(c, r, s));
            MinorArc a2 = (MinorArc)parser.Get(new MinorArc(c, t, u));
            MajorArc ma1 = (MajorArc)parser.Get(new MajorArc(c, r, s));
            MajorArc ma2 = (MajorArc)parser.Get(new MajorArc(c, t, u));

            goals.Add(new GeometricCongruentArcs(a1, a2));
            goals.Add(new GeometricCongruentArcs(ma1, ma2));
        }
Beispiel #3
0
        public static bool IntersectAtSamePoint(Segment seg1, Segment seg2, Segment seg3)
        {
            Point intersection1 = seg1.FindIntersection(seg3);
            Point intersection2 = seg2.FindIntersection(seg3);

            return(intersection1.Equals(intersection2));
        }
Beispiel #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));
        }
Beispiel #5
0
        //Demonstrates: ExteriorAngleHalfDifferenceInterceptedArcs : two secants
        public Test04(bool onoff, bool complete)
            : base(onoff, complete)
        {
            //Circle
            Point o = new Point("O", 0, 0); points.Add(o);
            Circle circleO = new Circle(o, 5.0);
            circles.Add(circleO);

            //Intersection point for two secants
            Point x = new Point("X", 0, 6); points.Add(x);

            //Secant intersection points for circle O
            Point a = new Point("A", -3, -4); points.Add(a);
            Point b = new Point("B", 3, -4); points.Add(b);
            Point c, d, trash;
            circleO.FindIntersection(new Segment(b, x), out c, out trash);
            if (b.StructurallyEquals(c)) c = trash;
            c = new Point("C", c.X, c.Y);
            points.Add(c);
            circleO.FindIntersection(new Segment(a, x), out d, out trash);
            if (a.StructurallyEquals(d)) d = trash;
            d = new Point("D", d.X, d.Y);
            points.Add(d);

            //Create point for another arc (Arc(CE)) of equal measure to (1/2)*(Arc(AB)-Arc(CD))
            Point e = new Point("E", 3, 4); points.Add(e);

            //Should now be able to form segments for a central angle of equal measure to (1/2)*(Arc(AB)-Arc(CD))
            Segment oc = new Segment(o, c); segments.Add(oc);
            Segment oe = new Segment(o, e); segments.Add(oe);

            //Label the intersection betweeen OE and BX
            Point i = oe.FindIntersection(new Segment(b, x));
            i = new Point("I", i.X, i.Y); points.Add(i);

            List<Point> pnts = new List<Point>();
            pnts.Add(a);
            pnts.Add(d);
            pnts.Add(x);
            collinear.Add(new Collinear(pnts));

            pnts = new List<Point>();
            pnts.Add(b);
            pnts.Add(i);
            pnts.Add(c);
            pnts.Add(x);
            collinear.Add(new Collinear(pnts));

            parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            MinorArc farMinor1 = (MinorArc)parser.Get(new MinorArc(circleO, a, b));
            MinorArc closeMinor1 = (MinorArc)parser.Get(new MinorArc(circleO, c, d));
            MinorArc centralAngleArc = (MinorArc)parser.Get(new MinorArc(circleO, c, e));
            given.Add(new GeometricArcEquation(new Multiplication(new NumericValue(2), centralAngleArc), new Subtraction(farMinor1, closeMinor1)));

            goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, x, b)), (Angle)parser.Get(new Angle(c, o, e))));
        }
Beispiel #6
0
        //
        // Creates a basic S-Shape with standsOnEndpoints
        //
        //   offThis   ______
        //                   |
        //   offThat   ______|
        //
        // Return <offThis, offThat>
        public KeyValuePair <Point, Point> CreatesBasicCShape(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 S-shape scenario
            Segment crossingTester = new Segment(offThis, offThat);
            Point   intersection   = transversal.FindIntersection(crossingTester);

            // We may have parallel crossingTester and transversal; that's ok
            if (crossingTester.IsParallelWith(transversal))
            {
                return(new KeyValuePair <Point, Point>(offThis, offThat));
            }

            // S-shape
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                return(nullPair);
            }

            // C-Shape
            return(new KeyValuePair <Point, Point>(offThis, offThat));
        }
Beispiel #7
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);
        }
Beispiel #8
0
        public static Circle ConstructCircle(Point p1, Point p2, Point p3)
        {
            //
            // Find the center of the circle.
            //
            Segment chord1 = new Segment(p1, p2);
            Segment chord2 = new Segment(p2, p3);

            Segment perpBis1 = chord1.GetPerpendicular(chord1.Midpoint());
            Segment perpBis2 = chord2.GetPerpendicular(chord2.Midpoint());

            Point center = perpBis1.FindIntersection(perpBis2);

            //
            // Radius is the distance between the circle and any of the original points.
            //
            return(new Circle(center, Point.calcDistance(center, p1)));
        }
Beispiel #9
0
        //Demonstrates: If two inscribed angles intercept the same arc, the angles are congruent
        public Test08(bool onoff, bool complete)
            : base(onoff, complete)
        {
            //Points for chord BAC
            Point a = new Point("A", -1, -System.Math.Sqrt(24)); points.Add(a);
            Point b = new Point("B", -3, 4); points.Add(b);
            Point c = new Point("C", 2, System.Math.Sqrt(21)); points.Add(c);

            //Points for angle BDC
            Point d = new Point("D", 3, -4); points.Add(d);

            //Lable the intersection between BD and AC
            Segment ac = new Segment(a, c);
            Segment db = new Segment(d, b);
            Point i = ac.FindIntersection(db);
            i = new Point("I", i.X, i.Y); points.Add(i);

            //Segments for both angles
            Segment ab = new Segment(a, b); segments.Add(ab);
            Segment dc = new Segment(d, c); segments.Add(dc);

            List<Point> pnts = new List<Point>();
            pnts.Add(a);
            pnts.Add(i);
            pnts.Add(c);
            collinear.Add(new Collinear(pnts));

            pnts = new List<Point>();
            pnts.Add(d);
            pnts.Add(i);
            pnts.Add(b);
            collinear.Add(new Collinear(pnts));

            //Circle
            Point o = new Point("O", 0, 0); points.Add(o);
            Circle circleO = new Circle(o, 5.0);
            circles.Add(circleO);

            parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(b, a, c)), (Angle)parser.Get(new Angle(b, d, c))));
        }
Beispiel #10
0
        //Demonstrates: Measure of an angle formed by two chords that intersect inside a circle is equal to half the sum of the measures
        //of the intercepted arcs
        //To see use of theorem, need to turn off VERTICAL_ANGLES and RELATIONS_OF_CONGRUENT_ANGLES_ARE_CONGRUENT in JustificationSwitch
        public Test07(bool onoff, bool complete)
            : base(onoff, complete)
        {
            //Circle
            Point o = new Point("O", 0, 0); points.Add(o);
            Circle circleO = new Circle(o, 5.0);
            circles.Add(circleO);

            //Points for chord ab
            Point a = new Point("A", -3, 4); points.Add(a);
            Point b = new Point("B", 3, -4); points.Add(b);

            //Points for chord cd
            Point c = new Point("C", -3, -4); points.Add(c);
            Point d = new Point("D", 1, System.Math.Sqrt(24)); points.Add(d);

            //Find intersection point of ab and cd
            Segment ab = new Segment(a, b);
            Segment cd = new Segment(c, d);
            Point inter = ab.FindIntersection(cd);
            Point z = new Point("Z", inter.X, inter.Y); points.Add(z);

            List<Point> pnts = new List<Point>();
            pnts.Add(a);
            pnts.Add(z);
            pnts.Add(b);
            collinear.Add(new Collinear(pnts));

            pnts = new List<Point>();
            pnts.Add(c);
            pnts.Add(z);
            pnts.Add(d);
            collinear.Add(new Collinear(pnts));

            parser = new LiveGeometry.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, z, d)), (Angle)parser.Get(new Angle(c, z, b))));
            goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, z, c)), (Angle)parser.Get(new Angle(b, z, d))));
        }
Beispiel #11
0
        //Demonstrates: Congruent chords have congruent arcs (and converse); arc addition axiom
        public Page309Problem09(bool onoff, bool complete)
            : base(onoff, complete)
        {
            Point o = new Point("O", 0, 0); points.Add(o);
            Point r = new Point("R", -3, 4); points.Add(r);
            Point s = new Point("S", 2, Math.Sqrt(21)); points.Add(s);
            Point t = new Point("T", 2, -Math.Sqrt(21)); points.Add(t);
            Point u = new Point("U", -3, -4); points.Add(u);

            Segment rt = new Segment(r, t);
            Segment su = new Segment(s, u);

            Point v = rt.FindIntersection(su); points.Add(v);

            Segment rs = new Segment(r, s); segments.Add(rs);
            Segment ut = new Segment(u, t); segments.Add(ut);

            List<Point> pnts = new List<Point>();
            pnts.Add(r);
            pnts.Add(v);
            pnts.Add(t);
            collinear.Add(new Collinear(pnts));

            pnts = new List<Point>();
            pnts.Add(s);
            pnts.Add(v);
            pnts.Add(u);
            collinear.Add(new Collinear(pnts));

            Circle c = new Circle(o, 5.0);
            circles.Add(c);

            parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            given.Add(new GeometricCongruentSegments((Segment)parser.Get(new Segment(r, s)), (Segment)parser.Get(new Segment(u, t))));

            goals.Add(new GeometricCongruentSegments((Segment)parser.Get(new Segment(r, t)), (Segment)parser.Get(new Segment(u, s))));
        }
Beispiel #12
0
        //Demonstrates: Inscribed angle half measure of intercepted arc and transitive substitution
        public Test03(bool onoff, bool complete)
            : base(onoff, complete)
        {
            Point o = new Point("O", 0, 0); points.Add(o);
            Point r = new Point("R", -3, 4); points.Add(r);
            Point t = new Point("T", 3, 4); points.Add(t);
            Point v = new Point("V", -3, -4); points.Add(v);
            Point x = new Point("X", 0, -5); points.Add(x);

            Segment vr = new Segment(v, r); segments.Add(vr);
            Segment tx = new Segment(t, x); segments.Add(tx);

            Segment vt = new Segment(v, t);
            Segment rx = new Segment(r, x);
            Point i = vt.FindIntersection(rx);
            i = new Point("I", i.X, i.Y); points.Add(i);

            List<Point> pnts = new List<Point>();
            pnts.Add(v);
            pnts.Add(i);
            pnts.Add(o);
            pnts.Add(t);
            collinear.Add(new Collinear(pnts));

            pnts = new List<Point>();
            pnts.Add(x);
            pnts.Add(i);
            pnts.Add(r);
            collinear.Add(new Collinear(pnts));

            Circle c = new Circle(o, 5.0);
            circles.Add(c);

            parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(i, v, r)), (Angle)parser.Get(new Angle(i, x, t))));
        }
Beispiel #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));
        }
Beispiel #14
0
        public static bool IntersectAtSamePoint(Segment seg1, Segment seg2, Segment seg3)
        {
            Point intersection1 = seg1.FindIntersection(seg3);
            Point intersection2 = seg2.FindIntersection(seg3);

            return intersection1.Equals(intersection2);
        }
Beispiel #15
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));
        }
Beispiel #16
0
        //
        // 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));
        }
Beispiel #17
0
        public Intersection GetIntersection(GeometryTutorLib.ConcreteAST.Segment segment1, GeometryTutorLib.ConcreteAST.Segment segment2)
        {
            Point inter = (Point)Get(segment1.FindIntersection(segment2));

            return((Intersection)Get(new Intersection(inter, segment1, segment2)));
        }
Beispiel #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));
        }
Beispiel #19
0
        public List<Area_Based_Analyses.Atomizer.AtomicRegion> Atomize(List<Point> figurePoints)
        {
            List<Segment> constructedChords = new List<Segment>();
            List<Segment> constructedRadii = new List<Segment>();
            List<Point> imagPoints = new List<Point>();

            List<Point> interPts = GetIntersectingPoints();

            //
            // Construct the radii
            //
            switch (interPts.Count)
            {
                // If there are no points of interest, the circle is the atomic region.
                case 0:
                  return Utilities.MakeList<AtomicRegion>(new ShapeAtomicRegion(this));

                // If only 1 intersection point, create the diameter.
                case 1:
                  Point opp = Utilities.AcquirePoint(figurePoints, this.OppositePoint(interPts[0]));
                  constructedRadii.Add(new Segment(center, interPts[0]));
                  constructedRadii.Add(new Segment(center, opp));
                  imagPoints.Add(opp);
                  interPts.Add(opp);
                  break;

                default:
                  foreach (Point interPt in interPts)
                  {
                      constructedRadii.Add(new Segment(center, interPt));
                  }
                  break;
            }

            //
            // Construct the chords
            //
            List<Segment> chords = new List<Segment>();
            for (int p1 = 0; p1 < interPts.Count - 1; p1++)
            {
                for (int p2 = p1 + 1; p2 < interPts.Count; p2++)
                {
                    Segment chord = new Segment(interPts[p1], interPts[p2]);
                    if (!DefinesDiameter(chord)) constructedChords.Add(chord);
                }
            }

            //
            // Do any of the created segments result in imaginary intersection points.
            //
            foreach (Segment chord in constructedChords)
            {
                foreach (Segment radius in constructedRadii)
                {
                    Point inter = Utilities.AcquireRestrictedPoint(figurePoints, chord.FindIntersection(radius), chord, radius);
                    if (inter != null)
                    {
                        chord.AddCollinearPoint(inter);
                        radius.AddCollinearPoint(inter);

                        // if (!Utilities.HasStructurally<Point>(figurePoints, inter)) imagPoints.Add(inter);
                        Utilities.AddUnique<Point>(imagPoints, inter);
                    }
                }
            }

            for (int c1 = 0; c1 < constructedChords.Count - 1; c1++)
            {
                for (int c2 = c1 + 1; c2 < constructedChords.Count; c2++)
                {
                    Point inter = constructedChords[c1].FindIntersection(constructedChords[c2]);
                    inter = Utilities.AcquireRestrictedPoint(figurePoints, inter, constructedChords[c1], constructedChords[c2]);
                    if (inter != null)
                    {
                        constructedChords[c1].AddCollinearPoint(inter);
                        constructedChords[c2].AddCollinearPoint(inter);

                        //if (!Utilities.HasStructurally<Point>(figurePoints, inter)) imagPoints.Add(inter);
                        Utilities.AddUnique<Point>(imagPoints, inter);
                    }
                }
            }

            //
            // Add all imaginary points to the list of figure points.
            //
            Utilities.AddUniqueList<Point>(figurePoints, imagPoints);

            //
            // Construct the Planar graph for atomic region identification.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph graph = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph();

            //
            // Add all imaginary points, intersection points, and center.
            //
            foreach (Point pt in imagPoints)
            {
                graph.AddNode(pt);
            }

            foreach (Point pt in interPts)
            {
                graph.AddNode(pt);
            }

            graph.AddNode(this.center);

            //
            // Add all chords and radii as edges.
            //
            foreach (Segment chord in constructedChords)
            {
                for (int p = 0; p < chord.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(chord.collinear[p], chord.collinear[p + 1],
                                            new Segment(chord.collinear[p], chord.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT);
                }
            }

            foreach (Segment radius in constructedRadii)
            {
                for (int p = 0; p < radius.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(radius.collinear[p], radius.collinear[p + 1],
                                            new Segment(radius.collinear[p], radius.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT);
                }
            }

            //
            // Add all arcs
            //
            List<Point> arcPts = this.ConstructAllMidpoints(interPts);
            for (int p = 0; p < arcPts.Count; p++)
            {
                graph.AddNode(arcPts[p]);
                graph.AddNode(arcPts[(p + 1) % arcPts.Count]);

                graph.AddUndirectedEdge(arcPts[p], arcPts[(p + 1) % arcPts.Count],
                                        new Segment(arcPts[p], arcPts[(p + 1) % interPts.Count]).Length,
                                        Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_ARC);
            }

            //
            // Convert the planar graph to atomic regions.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph copy = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph(graph);
            FacetCalculator atomFinder = new FacetCalculator(copy);
            List<Primitive> primitives = atomFinder.GetPrimitives();
            List<AtomicRegion> atoms = PrimitiveToRegionConverter.Convert(graph, primitives, Utilities.MakeList<Circle>(this));

            //
            // A filament may result in the creation of a major AND minor arc; both are not required.
            // Figure out which one to omit.
            // Multiple semi-circles may arise as well; omit if they can be broken into constituent elements.
            //
            List <AtomicRegion> trueAtoms = new List<AtomicRegion>();

            for (int a1 = 0; a1 < atoms.Count; a1++)
            {
                bool trueAtom = true;
                for (int a2 = 0; a2 < atoms.Count; a2++)
                {
                    if (a1 != a2)
                    {
                        if (atoms[a1].Contains(atoms[a2]))
                        {
                            trueAtom = false;
                            break;
                        }

                    }
                }

                if (trueAtom) trueAtoms.Add(atoms[a1]);
            }

            atoms = trueAtoms;

            return trueAtoms;
        }
Beispiel #20
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;
        }
Beispiel #21
0
        // return the midpoint between these two on the circle.
        public Point Midpoint(Point a, Point b, Point sameSide)
        {
            Point midpt = Midpoint(a, b);

            Segment segment = new Segment(a, b);
            Segment other = new Segment(midpt, sameSide);

            Point intersection = segment.FindIntersection(other);

            if (Segment.Between(intersection, midpt, sameSide)) return this.OppositePoint(midpt);

            return midpt;
        }
Beispiel #22
0
        //
        // 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;
        }
Beispiel #23
0
        //
        // This is a complex situation because we need to identify situations where circles intersect with the resultant regions:
        //    (|     (|)
        //   ( |    ( | )
        //  (  |   (  |  )
        //   ( |    ( | )
        //    (|     (|)
        //
        // Note: There will always be a chord because of our implied construction.
        // We are interested in only minor arcs of the given circles.
        //
        private List<Atomizer.AtomicRegion> ConvertToCircleCircle(Segment chord,
                                                                  List<Circle> circles,
                                                                  out Circle leftOuterCircle,
                                                                  out Circle rightOuterCircle)
        {
            List<Atomizer.AtomicRegion> regions = new List<Atomizer.AtomicRegion>();
            leftOuterCircle = null;
            rightOuterCircle = null;

            //
            // Simple cases that require no special attention.
            //
            if (!circles.Any()) return null;
            if (circles.Count == 1)
            {
                leftOuterCircle = circles[0];

                regions.AddRange(ConstructBasicLineCircleRegion(chord, circles[0]));

                return regions;
            }

            // All circles that are on each side of the chord
            List<Circle> leftSide = new List<Circle>();
            List<Circle> rightSide = new List<Circle>();

            // For now, assume max, one circle per side.
            // Construct a collinear list of points that includes all circle centers as well as the single intersection point between the chord and the line passing through all circle centers.
            // This orders the sides and provides implied sizes.

            Segment centerLine = new Segment(circles[0].center, circles[1].center);
            for (int c = 2; c < circles.Count; c++)
            {
                centerLine.AddCollinearPoint(circles[c].center);
            }
            // Find the intersection between the center-line and the chord; add that to the list.
            Point intersection = centerLine.FindIntersection(chord);
            centerLine.AddCollinearPoint(intersection);

            List<Point> collPoints = centerLine.collinear;
            int interIndex = collPoints.IndexOf(intersection);

            for (int i = 0; i < collPoints.Count; i++)
            {
                // find the circle based on center
                int c;
                for (c = 0; c < circles.Count; c++)
                {
                    if (circles[c].center.StructurallyEquals(collPoints[i])) break;
                }

                // Add the circle in order
                if (i < interIndex) leftSide.Add(circles[c]);
                else if (i > interIndex) rightSide.Add(circles[c]);
            }

            // the outermost circle is first in the left list and last in the right list.
            if (leftSide.Any()) leftOuterCircle = leftSide[0];
            if (rightSide.Any()) rightOuterCircle = rightSide[rightSide.Count - 1];

            //
            // Main combining algorithm:
            //     Assume: Increasing Arc sequence A \in A_1, A_2, ..., A_n and the single chord C
            //
            //     Construct region B = (C, A_1)
            //     For the increasing Arc sequence (k subscript)  A_2, A_3, ..., A_n
            //         B = Construct ((C, A_k) \ B)
            //
            // Alternatively:
            //     Construct(C, A_1)
            //     for each pair Construct (A_k, A_{k+1})
            //
            //
            // Handle each side: left and right.
            //
            if (leftSide.Any()) regions.AddRange(ConstructBasicLineCircleRegion(chord, leftSide[leftSide.Count - 1]));
            for (int ell = 0; ell < leftSide.Count - 2; ell++)
            {
                regions.Add(ConstructBasicCircleCircleRegion(chord, leftSide[ell], leftSide[ell + 1]));
            }

            if (rightSide.Any()) regions.AddRange(ConstructBasicLineCircleRegion(chord, rightSide[0]));
            for (int r = 1; r < rightSide.Count - 1; r++)
            {
                regions.Add(ConstructBasicCircleCircleRegion(chord, rightSide[r], rightSide[r + 1]));
            }

            return regions;
        }