//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 GeometryTutorLib.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)); }
// Construct the region between a circle and circle: // __ // ( ( // ( ( // ( ( // ( ( // ( ( // -- private Atomizer.AtomicRegion ConstructBasicCircleCircleRegion(Segment chord, Circle smaller, Circle larger) { AtomicRegion region = new AtomicRegion(); Arc arc1 = null; if (smaller.DefinesDiameter(chord)) { Point midpt = smaller.Midpoint(chord.Point1, chord.Point2, larger.Midpoint(chord.Point1, chord.Point2)); arc1 = new Semicircle(smaller, chord.Point1, chord.Point2, midpt, chord); } else { arc1 = new MinorArc(smaller, chord.Point1, chord.Point2); } MinorArc arc2 = new MinorArc(larger, chord.Point1, chord.Point2); region.AddConnection(chord.Point1, chord.Point2, ConnectionType.ARC, arc1); region.AddConnection(chord.Point1, chord.Point2, ConnectionType.ARC, arc2); return(region); }
//Demonstrates: Use of AngleArc equation, Central angle equal to intercepted arc public Test01(bool onoff, bool complete) : base(onoff, complete) { Point o = new Point("O", 0, 0); points.Add(o); Point a = new Point("A", -5, 0); points.Add(a); Point b = new Point("B", 5, 0); points.Add(b); Point c = new Point("C", 0, 5); points.Add(c); Segment oc = new Segment(o, c); segments.Add(oc); List <Point> pnts = new List <Point>(); pnts.Add(a); pnts.Add(o); pnts.Add(b); collinear.Add(new Collinear(pnts)); Circle circle = new Circle(o, 5.0); circles.Add(circle); parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); MinorArc m1 = (MinorArc)parser.Get(new MinorArc(circle, a, c)); MinorArc m2 = (MinorArc)parser.Get(new MinorArc(circle, b, c)); given.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, o, c)), (Angle)parser.Get(new Angle(b, o, c)))); goals.Add(new GeometricCongruentArcs(m1, m2)); }
// // A \ // \ B // \ / // O \/ X // /\ // / \ // C / D // // Two tangents: // Intersection(X, AD, BC), Tangent(Circle(O), BC), Tangent(Circle(O), AD) -> 2 * Angle(AXC) = MajorArc(AC) - MinorArc(AC) // public static List <EdgeAggregator> InstantiateTwoTangentsTheorem(Tangent tangent1, Tangent tangent2, Intersection inter, GroundedClause original1, GroundedClause original2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); CircleSegmentIntersection tan1 = tangent1.intersection as CircleSegmentIntersection; CircleSegmentIntersection tan2 = tangent2.intersection as CircleSegmentIntersection; if (tan1.StructurallyEquals(tan2)) { return(newGrounded); } // Do the tangents apply to the same circle? if (!tan1.theCircle.StructurallyEquals(tan2.theCircle)) { return(newGrounded); } Circle circle = tan1.theCircle; // Do these tangents work with this intersection? if (!inter.HasSegment(tan1.segment) || !inter.HasSegment(tan2.segment)) { return(newGrounded); } // Overkill? Do the tangents intersect at the same point as the intersection's intersect point? if (!tan1.segment.FindIntersection(tan2.segment).StructurallyEquals(inter.intersect)) { return(newGrounded); } // // Get the arcs // Arc minorArc = new MinorArc(circle, tan1.intersect, tan2.intersect); Arc majorArc = new MajorArc(circle, tan1.intersect, tan2.intersect); Angle theAngle = new Angle(tan1.intersect, inter.intersect, tan2.intersect); // // Construct the new relationship // NumericValue two = new NumericValue(2); GeometricAngleArcEquation gaaeq = new GeometricAngleArcEquation(new Multiplication(two, theAngle), new Subtraction(majorArc, minorArc)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original1); antecedent.Add(original2); antecedent.Add(inter); antecedent.Add(majorArc); antecedent.Add(minorArc); newGrounded.Add(new EdgeAggregator(antecedent, gaaeq, annotation)); return(newGrounded); }
public Page2Prob18(bool onoff, bool complete) : base(onoff, complete) { Point o = new Point("O", 0, 0); points.Add(o); Point a = new Point("A", 0, 4); points.Add(a); Point b = new Point("B", 4, 0); points.Add(b); Segment ab = new Segment(a, b); segments.Add(ab); Segment ao = new Segment(a, o); segments.Add(ao); Segment bo = new Segment(b, o); segments.Add(bo); Circle theCircle = new Circle(o, 4); circles.Add(theCircle); parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); MinorArc arcAB = (MinorArc)parser.Get(new MinorArc(theCircle, a, b)); given.Add(new GeometricArcEquation(arcAB, new NumericValue(90.0))); known.AddArcMeasureDegree(arcAB, 90.0); known.AddSegmentLength(ao, 4.0); known.AddSegmentLength(bo, 4.0); List <Point> wanted = new List <Point>(); wanted.Add(new Point("", 0, -1)); wanted.Add(new Point("", 1, 1)); goalRegions = parser.implied.GetAtomicRegionsByPoints(wanted); SetSolutionArea(45.69911184); problemName = "Jurgensen Page 2 Problem 18"; GeometryTutorLib.EngineUIBridge.HardCodedProblemsToUI.AddProblem(problemName, points, circles, segments); }
// // If one of the endpoints of that is inside of this; and vice versa. // public bool Overlap(Connection that) { if (that.type != this.type) { return(false); } if (this.type == ConnectionType.ARC) { if (!(this.segmentOrArc as Arc).StructurallyEquals(this.segmentOrArc as Arc)) { return(false); } // If the arcs just touch, it's not overlap. if (this.segmentOrArc is MinorArc) { MinorArc minor = this.segmentOrArc as MinorArc; if (minor.PointLiesStrictlyOn(that.endpoint1) || minor.PointLiesStrictlyOn(that.endpoint2)) { return(true); } } else if (this.segmentOrArc is Semicircle) { Semicircle semi = this.segmentOrArc as Semicircle; if (semi.PointLiesStrictlyOn(that.endpoint1) || semi.PointLiesStrictlyOn(that.endpoint2)) { return(true); } } else if (this.segmentOrArc is MajorArc) { MajorArc major = this.segmentOrArc as MajorArc; if (major.PointLiesStrictlyOn(that.endpoint1) || major.PointLiesStrictlyOn(that.endpoint2)) { return(true); } } return(false); } else if (this.type == ConnectionType.SEGMENT) { Segment thisSegment = this.segmentOrArc as Segment; Segment thatSegment = that.segmentOrArc as Segment; if (!thisSegment.IsCollinearWith(thatSegment)) { return(false); } return(thisSegment.CoincidingWithOverlap(thatSegment)); } return(false); }
private List <Atomizer.AtomicRegion> ConvertToTruncation(Segment chord, MinorArc arc) { AtomicRegion atom = new AtomicRegion(); atom.AddConnection(new Connection(chord.Point1, chord.Point2, ConnectionType.SEGMENT, chord)); atom.AddConnection(new Connection(chord.Point1, chord.Point2, ConnectionType.ARC, arc)); return(Utilities.MakeList <AtomicRegion>(atom)); }
public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.ARC_ADDITION_AXIOM; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); ArcInMiddle im = c as ArcInMiddle; if (im == null) { return(newGrounded); } Addition sum = null; // Temporarily assume that the two arcs formed by the intersection are both minor arcs MinorArc a1 = new MinorArc(im.arc.theCircle, im.arc.endpoint1, im.point); MinorArc a2 = new MinorArc(im.arc.theCircle, im.point, im.arc.endpoint2); // If the intersected arc is a minor arc, this will always be true. // If the intersected arc is a major arc, this might be true. Other case is one minor arc and one major arc. if (Arc.BetweenMajor(im.point, im.arc)) { // Check if both arcs are genuinely minor arcs. // If the other endpoint falls in the new arc, then the major arc should be used instead if (Arc.BetweenMinor(im.arc.endpoint2, a1)) { MajorArc majorArc = new MajorArc(im.arc.theCircle, im.arc.endpoint1, im.point); sum = new Addition(majorArc, a2); } else if (Arc.BetweenMinor(im.arc.endpoint1, a2)) { MajorArc majorArc = new MajorArc(im.arc.theCircle, im.point, im.arc.endpoint2); sum = new Addition(a1, majorArc); } } if (sum == null) { sum = new Addition(a1, a2); } GeometricArcEquation eq = new GeometricArcEquation(sum, im.arc); eq.MakeAxiomatic(); // For hypergraph List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(im); newGrounded.Add(new EdgeAggregator(antecedent, eq, annotation)); return(newGrounded); }
public Page6Row3Prob32b(bool onoff, bool complete) : base(onoff, complete) { double x = 8 * System.Math.Cos(36 * System.Math.PI / 180); double y = 8 * System.Math.Sin(36 * System.Math.PI / 180); Point r = new Point("R", -x, y); points.Add(r); Point p = new Point("P", 0, 0); points.Add(p); Point s = new Point("S", x, y); points.Add(s); Point q = new Point("Q", 0, -4); points.Add(q); Segment rp = new Segment(r, p); segments.Add(rp); Segment ps = new Segment(p, s); segments.Add(ps); Segment pq = new Segment(p, q); segments.Add(pq); Circle outer = new Circle(p, 8); Circle inner = new Circle(q, 4); circles.Add(outer); circles.Add(inner); parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); MinorArc m = (MinorArc)parser.Get(new MinorArc(outer, r, s)); known.AddSegmentLength(pq, 4); known.AddArcMeasureDegree(m, 108); given.Add(new GeometricArcEquation(m, new NumericValue(108))); List <Point> wanted = new List <Point>(); wanted.Add(new Point("", -6, 0)); wanted.Add(new Point("", -2, 0)); wanted.Add(new Point("", 2, 0)); wanted.Add(new Point("", 6, 0)); goalRegions = parser.implied.GetAtomicRegionsByPoints(wanted); SetSolutionArea(90.47786842); problemName = "McDougall Page 6 Row 3 Problem 32b"; GeometryTutorLib.EngineUIBridge.HardCodedProblemsToUI.AddProblem(problemName, points, circles, segments); }
private void CreateMajorMinorArcs(Circle circle, int p1, int p2) { List <Point> minorArcPoints; List <Point> majorArcPoints; PartitionArcPoints(circle, p1, p2, out minorArcPoints, out majorArcPoints); MinorArc newMinorArc = new MinorArc(circle, circle.pointsOnCircle[p1], circle.pointsOnCircle[p2], minorArcPoints, majorArcPoints); MajorArc newMajorArc = new MajorArc(circle, circle.pointsOnCircle[p1], circle.pointsOnCircle[p2], minorArcPoints, majorArcPoints); Sector newMinorSector = new Sector(newMinorArc); Sector newMajorSector = new Sector(newMajorArc); if (!GeometryTutorLib.Utilities.HasStructurally <MinorArc>(minorArcs, newMinorArc)) { minorArcs.Add(newMinorArc); minorSectors.Add(newMinorSector); majorSectors.Add(newMajorSector); angles.Add(new Angle(circle.pointsOnCircle[p1], circle.center, circle.pointsOnCircle[p2])); } if (!GeometryTutorLib.Utilities.HasStructurally <MajorArc>(majorArcs, newMajorArc)) { majorArcs.Add(newMajorArc); majorSectors.Add(newMajorSector); } circle.AddMinorArc(newMinorArc); circle.AddMajorArc(newMajorArc); circle.AddMinorSector(newMinorSector); circle.AddMajorSector(newMajorSector); // Generate ArcInMiddle clauses for minor arc and major arc for (int imIndex = 0; imIndex < newMinorArc.arcMinorPoints.Count; imIndex++) { GeometryTutorLib.Utilities.AddStructurallyUnique <ArcInMiddle>(arcInMiddle, new ArcInMiddle(newMinorArc.arcMinorPoints[imIndex], newMinorArc)); } for (int imIndex = 0; imIndex < newMajorArc.arcMajorPoints.Count; imIndex++) { GeometryTutorLib.Utilities.AddStructurallyUnique <ArcInMiddle>(arcInMiddle, new ArcInMiddle(newMajorArc.arcMajorPoints[imIndex], newMajorArc)); } }
//Demonstrates: ChordTangentAngleHalfInterceptedArc public Test02(bool onoff, bool complete) : base(onoff, complete) { Point o = new Point("O", 0, 0); points.Add(o); Point r = new Point("R", -3, -5); points.Add(r); Point s = new Point("S", 8, -5); points.Add(s); Point t = new Point("T", 0, -5); points.Add(t); Point u = new Point("U", -3, 4); points.Add(u); Point v = new Point("V", 3, 4); points.Add(v); Segment tu = new Segment(t, u); segments.Add(tu); Segment tv = new Segment(t, v); segments.Add(tv); List <Point> pnts = new List <Point>(); pnts.Add(r); pnts.Add(t); pnts.Add(s); 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); MinorArc m1 = (MinorArc)parser.Get(new MinorArc(c, t, u)); MinorArc m2 = (MinorArc)parser.Get(new MinorArc(c, t, v)); Segment rs = (Segment)parser.Get(new Segment(r, s)); CircleSegmentIntersection cInter = (CircleSegmentIntersection)parser.Get(new CircleSegmentIntersection(t, c, rs)); given.Add(new Strengthened(cInter, new Tangent(cInter))); given.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(r, t, u)), (Angle)parser.Get(new Angle(s, t, v)))); goals.Add(new GeometricCongruentArcs(m1, m2)); }
// Construct the region between a chord and the circle arc: // (| // ( | // ( | // ( | // (| // private List <AtomicRegion> ConstructBasicLineCircleRegion(Segment chord, Circle circle) { // // Standard // if (!circle.DefinesDiameter(chord)) { AtomicRegion region = new AtomicRegion(); Arc theArc = new MinorArc(circle, chord.Point1, chord.Point2); region.AddConnection(chord.Point1, chord.Point2, ConnectionType.ARC, theArc); region.AddConnection(chord.Point1, chord.Point2, ConnectionType.SEGMENT, chord); return(Utilities.MakeList <AtomicRegion>(region)); } // // Semi-circles // Point midpt = circle.Midpoint(chord.Point1, chord.Point2); Arc semi1 = new Semicircle(circle, chord.Point1, chord.Point2, midpt, chord); ShapeAtomicRegion region1 = new ShapeAtomicRegion(new Sector(semi1)); Point opp = circle.OppositePoint(midpt); Arc semi2 = new Semicircle(circle, chord.Point1, chord.Point2, opp, chord); ShapeAtomicRegion region2 = new ShapeAtomicRegion(new Sector(semi2)); List <AtomicRegion> regions = new List <AtomicRegion>(); regions.Add(region1); regions.Add(region2); return(regions); }
public Page2Prob20(bool onoff, bool complete) : base(onoff, complete) { double x = System.Math.Sqrt(3); double y = 1; Point a = new Point("A", -x, y); points.Add(a); Point b = new Point("B", x, y); points.Add(b); Point c = new Point("C", -x, -y); points.Add(c); Point d = new Point("D", x, -y); points.Add(d); Point o = new Point("O", 0, 0); points.Add(o); Segment ab = new Segment(a, b); segments.Add(ab); Segment cd = new Segment(c, d); segments.Add(cd); Segment ac = new Segment(a, c); segments.Add(ac); //Segment bd = new Segment(b, d); segments.Add(bd); List <Point> pnts = new List <Point>(); pnts.Add(a); pnts.Add(o); pnts.Add(d); collinear.Add(new Collinear(pnts)); pnts = new List <Point>(); pnts.Add(b); pnts.Add(o); pnts.Add(c); collinear.Add(new Collinear(pnts)); Circle circle = new Circle(o, 2); circles.Add(circle); parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); MinorArc arcAB = (MinorArc)parser.Get(new MinorArc(circle, a, b)); MinorArc arcBD = (MinorArc)parser.Get(new MinorArc(circle, b, d)); MinorArc arcDC = (MinorArc)parser.Get(new MinorArc(circle, d, c)); MinorArc arcAC = (MinorArc)parser.Get(new MinorArc(circle, a, c)); known.AddSegmentLength(ac, 2); known.AddArcMeasureDegree(arcAB, 120); known.AddArcMeasureDegree(arcBD, 60); known.AddArcMeasureDegree(arcDC, 120); known.AddArcMeasureDegree(arcAC, 60); given.Add(new GeometricArcEquation(arcAB, new NumericValue(120))); given.Add(new GeometricArcEquation(arcBD, new NumericValue(60))); given.Add(new GeometricArcEquation(arcDC, new NumericValue(120))); given.Add(new GeometricArcEquation(arcAC, new NumericValue(60))); List <Point> unwanted = new List <Point>(); unwanted.Add(new Point("", 0, y + 0.2)); unwanted.Add(new Point("", 0, -y - 0.2)); goalRegions = parser.implied.GetAllAtomicRegionsWithoutPoints(unwanted); SetSolutionArea((4.0 / 3.0) * System.Math.PI + 2.0 * System.Math.Sqrt(3.0)); problemName = "Jurgensen Page 2 Problem 20"; GeometryTutorLib.EngineUIBridge.HardCodedProblemsToUI.AddProblem(problemName, points, circles, segments); }
//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 LiveGeometry.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)))); }
private List <Atomizer.AtomicRegion> MixedArcChordedRegion(List <Circle> thatCircles, UndirectedPlanarGraph.PlanarGraph graph) { List <AtomicRegion> regions = new List <AtomicRegion>(); // Every segment may be have a set of circles. (on each side) surrounding it. // Keep parallel lists of: (1) segments, (2) (real) arcs, (3) left outer circles, and (4) right outer circles Segment[] regionsSegments = new Segment[points.Count]; Arc[] arcSegments = new Arc[points.Count]; Circle[] leftOuterCircles = new Circle[points.Count]; Circle[] rightOuterCircles = new Circle[points.Count]; // // Populate the parallel arrays. // int currCounter = 0; for (int p = 0; p < points.Count;) { UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p], points[(p + 1) % points.Count]); Segment currSegment = new Segment(points[p], points[(p + 1) % points.Count]); // // If a known segment, seek a sequence of collinear segments. // if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_SEGMENT) { Segment actualSeg = currSegment; bool collinearExists = false; int prevPtIndex; for (prevPtIndex = p + 1; prevPtIndex < points.Count; prevPtIndex++) { // Make another segment with the next point. Segment nextSeg = new Segment(points[p], points[(prevPtIndex + 1) % points.Count]); // CTA: This criteria seems invalid in some cases....; may not have collinearity // We hit the end of the line of collinear segments. if (!currSegment.IsCollinearWith(nextSeg)) { break; } collinearExists = true; actualSeg = nextSeg; } // If there exists an arc over the actual segment, we have an embedded circle to consider. regionsSegments[currCounter] = actualSeg; if (collinearExists) { UndirectedPlanarGraph.PlanarGraphEdge collEdge = graph.GetEdge(actualSeg.Point1, actualSeg.Point2); if (collEdge != null) { if (collEdge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC) { // Find all applicable circles List <Circle> circles = GetAllApplicableCircles(thatCircles, actualSeg.Point1, actualSeg.Point2); // Get the exact outer circles for this segment (and create any embedded regions). regions.AddRange(ConvertToCircleCircle(actualSeg, circles, out leftOuterCircles[currCounter], out rightOuterCircles[currCounter])); } } } currCounter++; p = prevPtIndex; } else if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_DUAL) { regionsSegments[currCounter] = new Segment(points[p], points[(p + 1) % points.Count]); // Get the exact chord and set of circles Segment chord = regionsSegments[currCounter]; // Find all applicable circles List <Circle> circles = GetAllApplicableCircles(thatCircles, points[p], points[(p + 1) % points.Count]); // Get the exact outer circles for this segment (and create any embedded regions). regions.AddRange(ConvertToCircleCircle(chord, circles, out leftOuterCircles[currCounter], out rightOuterCircles[currCounter])); currCounter++; p++; } else if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC) { // // Find the unique circle that contains these two points. // (if more than one circle has these points, we would have had more intersections and it would be a direct chorded region) // List <Circle> circles = GetAllApplicableCircles(thatCircles, points[p], points[(p + 1) % points.Count]); if (circles.Count != 1) { throw new Exception("Need ONLY 1 circle for REAL_ARC atom id; found (" + circles.Count + ")"); } arcSegments[currCounter++] = new MinorArc(circles[0], points[p], points[(p + 1) % points.Count]); p++; } } // // Check to see if this is a region in which some connections are segments and some are arcs. // This means there were no REAL_DUAL edges. // List <AtomicRegion> generalRegions = GeneralAtomicRegion(regionsSegments, arcSegments); if (generalRegions.Any()) { return(generalRegions); } // Copy the segments into a list (ensuring no nulls) List <Segment> actSegments = new List <Segment>(); foreach (Segment side in regionsSegments) { if (side != null) { actSegments.Add(side); } } // Construct a polygon out of the straight-up segments // This might be a polygon that defines a pathological region. Polygon poly = Polygon.MakePolygon(actSegments); // Determine which outermost circles apply inside of this polygon. Circle[] circlesCutInsidePoly = new Circle[actSegments.Count]; for (int p = 0; p < actSegments.Count; p++) { if (leftOuterCircles[p] != null && rightOuterCircles[p] == null) { circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, leftOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2); } else if (leftOuterCircles[p] == null && rightOuterCircles[p] != null) { circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, rightOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2); } else if (leftOuterCircles[p] != null && rightOuterCircles[p] != null) { circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, leftOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2); if (circlesCutInsidePoly[p] == null) { circlesCutInsidePoly[p] = rightOuterCircles[p]; } } else { circlesCutInsidePoly[p] = null; } } bool isStrictPoly = true; for (int p = 0; p < actSegments.Count; p++) { if (circlesCutInsidePoly[p] != null || arcSegments[p] != null) { isStrictPoly = false; break; } } // This is just a normal shape region: polygon. if (isStrictPoly) { regions.Add(new ShapeAtomicRegion(poly)); } // A circle cuts into the polygon. else { // // Now that all interior arcs have been identified, construct the atomic (probably pathological) region // AtomicRegion pathological = new AtomicRegion(); for (int p = 0; p < actSegments.Count; p++) { // // A circle cutting inside the polygon // if (circlesCutInsidePoly[p] != null) { Arc theArc = null; if (circlesCutInsidePoly[p].DefinesDiameter(regionsSegments[p])) { Point midpt = circlesCutInsidePoly[p].Midpoint(regionsSegments[p].Point1, regionsSegments[p].Point2); if (!poly.IsInPolygon(midpt)) { midpt = circlesCutInsidePoly[p].OppositePoint(midpt); } theArc = new Semicircle(circlesCutInsidePoly[p], regionsSegments[p].Point1, regionsSegments[p].Point2, midpt, regionsSegments[p]); } else { theArc = new MinorArc(circlesCutInsidePoly[p], regionsSegments[p].Point1, regionsSegments[p].Point2); } pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2, ConnectionType.ARC, theArc); } // else { // We have a direct arc if (arcSegments[p] != null) { pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2, ConnectionType.ARC, arcSegments[p]); } // Use the segment else { pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2, ConnectionType.SEGMENT, regionsSegments[p]); } } } regions.Add(pathological); } return(regions); }
// // C // /) // / ) // / ) // / ) // A /)_________ B // // Tangent(Circle(O), Segment(AB)), Intersection(Segment(AC), Segment(AB)) -> 2 * Angle(CAB) = Arc(C, B) // public static List <EdgeAggregator> InstantiateTheorem(Intersection inter, Tangent tangent, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); CircleSegmentIntersection tan = tangent.intersection as CircleSegmentIntersection; // // Does this tangent apply to this intersection? // if (!inter.intersect.StructurallyEquals(tangent.intersection.intersect)) { return(newGrounded); } Segment secant = null; Segment tanSegment = null; if (tan.HasSegment(inter.lhs)) { secant = inter.rhs; tanSegment = inter.lhs; } else if (tan.HasSegment(inter.rhs)) { secant = inter.lhs; tanSegment = inter.rhs; } else { return(newGrounded); } // // Acquire the angle and intercepted arc. // Segment chord = tan.theCircle.GetChord(secant); if (chord == null) { return(newGrounded); } //Segment chord = tan.theCircle.ContainsChord(secant); // Arc // We want the MINOR ARC only! if (tan.theCircle.DefinesDiameter(chord)) { Arc theArc = null; Point midpt = PointFactory.GeneratePoint(tan.theCircle.Midpoint(chord.Point1, chord.Point2)); Point opp = PointFactory.GeneratePoint(tan.theCircle.OppositePoint(midpt)); Point tanPoint = tanSegment.OtherPoint(inter.intersect); if (tanPoint != null) { // Angle; the smaller angle is always the chosen angle Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanPoint); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); } else { // Angle; the smaller angle is always the chosen angle Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point1); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); // Angle; the smaller angle is always the chosen angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point2); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); } } else { Arc theArc = new MinorArc(tan.theCircle, chord.Point1, chord.Point2); // Angle; the smaller angle is always the chosen angle Point endPnt = (inter.intersect.StructurallyEquals(tanSegment.Point1)) ? tanSegment.Point2 : tanSegment.Point1; Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, endPnt); if (theAngle.measure > 90) { //If the angle endpoint was already set to Point2, or if the intersect equals Point2, then the smaller angle does not exist //In this case, should we create a major arc or return nothing? if (endPnt.StructurallyEquals(tanSegment.Point2) || inter.intersect.StructurallyEquals(tanSegment.Point2)) { return(newGrounded); } theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point2); } Multiplication product = new Multiplication(new NumericValue(2), theAngle); GeometricAngleArcEquation angArcEq = new GeometricAngleArcEquation(product, theArc); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); antecedent.Add(theArc); antecedent.Add(theAngle); newGrounded.Add(new EdgeAggregator(antecedent, angArcEq, annotation)); } return(newGrounded); }
// // Order the arcs so the endpoints are clear in the first in last positions. // private List <MinorArc> SortArcSet(List <MinorArc> arcs) { if (arcs.Count <= 2) { return(arcs); } bool[] marked = new bool[arcs.Count]; List <MinorArc> sorted = new List <MinorArc>(); // // Find the 'first' endpoint of the arc. // int sharedCount = 0; int arcIndex = -1; for (int a1 = 0; a1 < arcs.Count; a1++) { sharedCount = 0; for (int a2 = 0; a2 < arcs.Count; a2++) { if (a1 != a2) { if (arcs[a1].SharedEndpoint(arcs[a2]) != null) { sharedCount++; } } } arcIndex = a1; if (sharedCount == 1) { break; } } // An 'end'-arc found; book-ends of list. switch (sharedCount) { case 0: throw new Exception("Expected a shared count of 1 or 2, not 0"); case 1: sorted.Add(arcs[arcIndex]); marked[arcIndex] = true; break; case 2: // Middle arc break; default: throw new Exception("Expected a shared count of 1 or 2, not (" + sharedCount + ")"); } MinorArc working = sorted[0]; while (marked.Contains(false)) { Point shared; for (arcIndex = 0; arcIndex < arcs.Count; arcIndex++) { if (!marked[arcIndex]) { shared = working.SharedEndpoint(arcs[arcIndex]); if (shared != null) { break; } } } marked[arcIndex] = true; sorted.Add(arcs[arcIndex]); working = arcs[arcIndex]; } return(sorted); }
//Demonstrates: ExteriorAngleHalfDifferenceInterceptedArcs : one tangent, one secant public Test06(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 tangent & secant Point c = new Point("C", 0, 6.25); points.Add(c); //Points for tangent line ac, intersection at b Point a = new Point("A", -8, 0.25); points.Add(a); Point b = new Point("B", -3, 4); points.Add(b); //Points for secant line ce, intersections at D & E Point d = new Point("D", 0, 5); points.Add(d); Point e = new Point("E", 0, -5); points.Add(e); //Create point for another arc (Arc(DF)) of equal measure to (1/2)*(MinorArc(BE)-MinorArc(BD)) MinorArc farMinor = new MinorArc(circleO, b, e); MinorArc closeMinor = new MinorArc(circleO, b, d); double measure = (farMinor.GetMinorArcMeasureDegrees() - closeMinor.GetMinorArcMeasureDegrees()) / 2; //Get theta for F double dThetaDegrees = 90; double fThetaRadians = (dThetaDegrees - measure) * (System.Math.PI / 180); //Get coordinates for F Point unitPnt = new Point("", System.Math.Cos(fThetaRadians), System.Math.Sin(fThetaRadians)); Point f, trash; circleO.FindIntersection(new Segment(o, unitPnt), out f, out trash); if (f.X < 0) { f = trash; } f = new Point("F", f.X, f.Y); points.Add(f); //Should now be able to form segments for a central angle of equal measure to (1/2)*(Arc(AB)-Arc(CD)) Segment od = new Segment(o, d); segments.Add(od); Segment of = new Segment(o, f); segments.Add(of); List <Point> pnts = new List <Point>(); pnts.Add(a); pnts.Add(b); pnts.Add(c); collinear.Add(new Collinear(pnts)); pnts = new List <Point>(); pnts.Add(c); pnts.Add(d); pnts.Add(e); collinear.Add(new Collinear(pnts)); parser = new GeometryTutorLib.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); Segment ac = (Segment)parser.Get(new Segment(a, c)); CircleSegmentIntersection cInter = (CircleSegmentIntersection)parser.Get(new CircleSegmentIntersection(b, circleO, ac)); given.Add(new Strengthened(cInter, new Tangent(cInter))); MinorArc far = (MinorArc)parser.Get(new MinorArc(circleO, b, e)); MinorArc close = (MinorArc)parser.Get(new MinorArc(circleO, b, d)); MinorArc centralAngleArc = (MinorArc)parser.Get(new MinorArc(circleO, d, f)); given.Add(new GeometricArcEquation(new Multiplication(new NumericValue(2), centralAngleArc), new Subtraction(far, close))); goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, c, e)), (Angle)parser.Get(new Angle(d, o, f)))); }
//Demonstrates: ExteriorAngleHalfDifferenceInterceptedArcs : two tangents //Demonstrates: Tangents from point are congruent public Test05(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 tangents Point c = new Point("C", 0, 6.25); points.Add(c); //Points for tangent line ac, intersection at b Point a = new Point("A", -8, 0.25); points.Add(a); Point b = new Point("B", -3, 4); points.Add(b); //Points for tangent line ec, intersection at d Point e = new Point("E", 8, 0.25); points.Add(e); Point d = new Point("D", 3, 4); points.Add(d); //Create point for another arc (Arc(DF)) of equal measure to (1/2)*(MajorArc(BD)-MinorArc(BD)) MinorArc minor = new MinorArc(circleO, b, d); MajorArc major = new MajorArc(circleO, b, d); double measure = (major.GetMajorArcMeasureDegrees() - minor.GetMinorArcMeasureDegrees()) / 2; //Get theta for D and E Circle unit = new Circle(o, 1.0); Point inter1, trash; unit.FindIntersection(new Segment(o, d), out inter1, out trash); if (inter1.X < 0) { inter1 = trash; } double dThetaDegrees = (System.Math.Acos(inter1.X)) * (180 / System.Math.PI); double fThetaRadians = (dThetaDegrees - measure) * (System.Math.PI / 180); //Get coordinates for E Point unitPnt = new Point("", System.Math.Cos(fThetaRadians), System.Math.Sin(fThetaRadians)); Point f; circleO.FindIntersection(new Segment(o, unitPnt), out f, out trash); if (f.X < 0) { f = trash; } f = new Point("F", f.X, f.Y); points.Add(f); //Should now be able to form segments for a central angle of equal measure to (1/2)*(Arc(AB)-Arc(CD)) Segment od = new Segment(o, d); segments.Add(od); Segment of = new Segment(o, f); segments.Add(of); List <Point> pnts = new List <Point>(); pnts.Add(a); pnts.Add(b); pnts.Add(c); collinear.Add(new Collinear(pnts)); pnts = new List <Point>(); pnts.Add(c); pnts.Add(d); pnts.Add(e); collinear.Add(new Collinear(pnts)); parser = new LiveGeometry.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff); Segment ac = (Segment)parser.Get(new Segment(a, c)); Segment ce = (Segment)parser.Get(new Segment(c, e)); CircleSegmentIntersection cInter = (CircleSegmentIntersection)parser.Get(new CircleSegmentIntersection(b, circleO, ac)); CircleSegmentIntersection cInter2 = (CircleSegmentIntersection)parser.Get(new CircleSegmentIntersection(d, circleO, ce)); given.Add(new Strengthened(cInter, new Tangent(cInter))); given.Add(new Strengthened(cInter2, new Tangent(cInter2))); MinorArc a1 = (MinorArc)parser.Get(new MinorArc(circleO, b, d)); MajorArc a2 = (MajorArc)parser.Get(new MajorArc(circleO, b, d)); MinorArc centralAngleArc = (MinorArc)parser.Get(new MinorArc(circleO, d, f)); given.Add(new GeometricArcEquation(new Multiplication(new NumericValue(2), centralAngleArc), new Subtraction(a2, a1))); goals.Add(new GeometricCongruentAngles((Angle)parser.Get(new Angle(a, c, e)), (Angle)parser.Get(new Angle(d, o, f)))); goals.Add(new GeometricCongruentSegments((Segment)parser.Get(new Segment(b, c)), (Segment)parser.Get(new Segment(c, d)))); }
// A // /) // / ) // / ) // center: O ) // \ ) // \ ) // \) // C // // D // /) // / ) // / ) // center: Q ) // \ ) // \ ) // \) // F // // Congruent(Segment(AC), Segment(DF)) -> Congruent(Arc(A, C), Arc(D, F)) // private static List <EdgeAggregator> InstantiateForwardPartOfTheorem(CongruentSegments cas) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // // Acquire the circles for which the segments are chords. // List <Circle> circles1 = Circle.GetChordCircles(cas.cs1); List <Circle> circles2 = Circle.GetChordCircles(cas.cs2); // // Make all possible combinations of arcs congruent // foreach (Circle circle1 in circles1) { // Create the appropriate type of arcs from the chord and the circle List <Semicircle> c1semi = null; MinorArc c1minor = null; MajorArc c1major = null; if (circle1.DefinesDiameter(cas.cs1)) { c1semi = CreateSemiCircles(circle1, cas.cs1); } else { c1minor = new MinorArc(circle1, cas.cs1.Point1, cas.cs1.Point2); c1major = new MajorArc(circle1, cas.cs1.Point1, cas.cs1.Point2); } foreach (Circle circle2 in circles2) { //The two circles must be the same or congruent if (circle1.radius == circle2.radius) { List <Semicircle> c2semi = null; MinorArc c2minor = null; MajorArc c2major = null; List <GeometricCongruentArcs> congruencies = new List <GeometricCongruentArcs>(); if (circle2.DefinesDiameter(cas.cs2)) { c2semi = CreateSemiCircles(circle2, cas.cs2); congruencies.AddRange(EquateSemiCircles(c1semi, c2semi)); } else { c2minor = new MinorArc(circle2, cas.cs2.Point1, cas.cs2.Point2); c2major = new MajorArc(circle2, cas.cs2.Point1, cas.cs2.Point2); congruencies.Add(new GeometricCongruentArcs(c1minor, c2minor)); congruencies.Add(new GeometricCongruentArcs(c1major, c2major)); } // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(cas.cs1); antecedent.Add(cas.cs2); antecedent.Add(cas); foreach (GeometricCongruentArcs gcas in congruencies) { newGrounded.Add(new EdgeAggregator(antecedent, gcas, forwardAnnotation)); } } } } return(newGrounded); }