public override bool Equals(Object obj) { MinorArc arc = obj as MinorArc; if (arc == null) { return(false); } // Check equality of arc minor / major points? return(base.Equals(obj)); }
// Checking for structural equality (is it the same segment) excluding the multiplier public override bool StructurallyEquals(object obj) { MinorArc arc = obj as MinorArc; if (arc == null) { return(false); } return(this.theCircle.StructurallyEquals(arc.theCircle) && ((this.endpoint1.StructurallyEquals(arc.endpoint1) && this.endpoint2.StructurallyEquals(arc.endpoint2)) || (this.endpoint1.StructurallyEquals(arc.endpoint2) && this.endpoint2.StructurallyEquals(arc.endpoint1)))); }
public static Arc GetFigureMinorArc(Circle circle, Point pt1, Point pt2) { MinorArc candArc = new MinorArc(circle, pt1, pt2); // Search for exact segment first foreach (MinorArc arc in figureMinorArcs) { if (arc.StructurallyEquals(candArc)) { return(arc); } } return(null); }
public override bool CoordinateCongruent(Figure that) { MinorArc thatArc = that as MinorArc; if (thatArc == null) { return(false); } if (!theCircle.CoordinateCongruent(thatArc.theCircle)) { return(false); } return(Utilities.CompareValues(this.GetMinorArcMeasureDegrees(), thatArc.GetMinorArcMeasureDegrees())); }
private static Arc GetInscribedInterceptedArc(Circle circle, Angle angle) { Point endpt1, endpt2; Point pt1, pt2; circle.FindIntersection(angle.ray1, out pt1, out pt2); endpt1 = pt1.StructurallyEquals(angle.GetVertex()) ? pt2 : pt1; circle.FindIntersection(angle.ray2, out pt1, out pt2); endpt2 = pt1.StructurallyEquals(angle.GetVertex()) ? pt2 : pt1; // Need to check if the angle is a diameter and create a semicircle Segment chord = new Segment(endpt1, endpt2); if (circle.DefinesDiameter(chord)) { Point opp = circle.Midpoint(endpt1, endpt2, angle.GetVertex()); Semicircle semi = new Semicircle(circle, endpt1, endpt2, circle.OppositePoint(opp), chord); //Find a defined semicircle of the figure that lies on the same side Semicircle sameSideSemi = figureSemicircles.Where(s => semi.SameSideSemicircle(s)).FirstOrDefault(); //If none were found, should we throw an exception or just return the original semi? if (sameSideSemi == null) { return(semi); } else { return(sameSideSemi); } } //Initially assume intercepted arc is the minor arc Arc intercepted = null; intercepted = new MinorArc(circle, endpt1, endpt2); //Verify assumption, create major arc if necessary if (Arc.BetweenMinor(angle.GetVertex(), intercepted)) { intercepted = new MajorArc(circle, endpt1, endpt2); } return(intercepted); }
// // Is M between A and B in the minor arc // public static bool BetweenMinor(Point m, Arc originalArc) { if (m == null) { return(false); } // Is the point on this circle? if (!originalArc.theCircle.PointLiesOn(m)) { return(false); } // Create two arcs from this new point to the endpoints; just like with segments, // the sum of the arc measures must equate to the overall arc measure. MinorArc arc1 = new MinorArc(originalArc.theCircle, m, originalArc.endpoint1); MinorArc arc2 = new MinorArc(originalArc.theCircle, m, originalArc.endpoint2); return(Utilities.CompareValues(arc1.minorMeasure + arc2.minorMeasure, originalArc.minorMeasure)); }
public bool SameSideSemicircle(Semicircle thatSemi) { // First, the endpoints and the diameter must match if (!(this.diameter.StructurallyEquals(thatSemi.diameter) && base.StructurallyEquals(thatSemi))) { return(false); } // if either of the 2 minor arcs formed by this semicircle's middlepoint contain the middlepoint of thatSemi, // then the two semicircles form the same 'side' of the circle MinorArc m = new MinorArc(this.theCircle, this.endpoint1, this.middlePoint); MinorArc m2 = new MinorArc(this.theCircle, this.middlePoint, this.endpoint2); if (Arc.BetweenMinor(thatSemi.middlePoint, m) || Arc.BetweenMinor(thatSemi.middlePoint, m2)) { return(true); } else { 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); }
// 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; }
// // 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; }
// 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; }
// 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; }
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)); } }
private static Arc GetInscribedInterceptedArc(Circle circle, Angle angle) { Point endpt1, endpt2; Point pt1, pt2; circle.FindIntersection(angle.ray1, out pt1, out pt2); endpt1 = pt1.StructurallyEquals(angle.GetVertex()) ? pt2 : pt1; circle.FindIntersection(angle.ray2, out pt1, out pt2); endpt2 = pt1.StructurallyEquals(angle.GetVertex()) ? pt2 : pt1; // Need to check if the angle is a diameter and create a semicircle Segment chord = new Segment(endpt1, endpt2); if (circle.DefinesDiameter(chord)) { Point opp = circle.Midpoint(endpt1, endpt2, angle.GetVertex()); Semicircle semi = new Semicircle(circle, endpt1, endpt2, circle.OppositePoint(opp), chord); //Find a defined semicircle of the figure that lies on the same side Semicircle sameSideSemi = figureSemicircles.Where(s => semi.SameSideSemicircle(s)).FirstOrDefault(); //If none were found, should we throw an exception or just return the original semi? if (sameSideSemi == null) return semi; else return sameSideSemi; } //Initially assume intercepted arc is the minor arc Arc intercepted = null; intercepted = new MinorArc(circle, endpt1, endpt2); //Verify assumption, create major arc if necessary if (Arc.BetweenMinor(angle.GetVertex(), intercepted)) intercepted = new MajorArc(circle, endpt1, endpt2); return intercepted; }
// // Is M between A and B in the minor arc // public static bool BetweenMinor(Point m, Arc originalArc) { if (m == null) return false; // Is the point on this circle? if (!originalArc.theCircle.PointLiesOn(m)) return false; // Create two arcs from this new point to the endpoints; just like with segments, // the sum of the arc measures must equate to the overall arc measure. MinorArc arc1 = new MinorArc(originalArc.theCircle, m, originalArc.endpoint1); MinorArc arc2 = new MinorArc(originalArc.theCircle, m, originalArc.endpoint2); return Utilities.CompareValues(arc1.minorMeasure + arc2.minorMeasure, originalArc.minorMeasure); }
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; }
public bool SameSideSemicircle(Semicircle thatSemi) { // First, the endpoints and the diameter must match if (!(this.diameter.StructurallyEquals(thatSemi.diameter) && base.StructurallyEquals(thatSemi))) return false; // if either of the 2 minor arcs formed by this semicircle's middlepoint contain the middlepoint of thatSemi, // then the two semicircles form the same 'side' of the circle MinorArc m = new MinorArc(this.theCircle, this.endpoint1, this.middlePoint); MinorArc m2 = new MinorArc(this.theCircle, this.middlePoint, this.endpoint2); if (Arc.BetweenMinor(thatSemi.middlePoint, m) || Arc.BetweenMinor(thatSemi.middlePoint, m2)) return true; else return false; }
// // 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; }
public static Arc GetFigureMinorArc(Circle circle, Point pt1, Point pt2) { MinorArc candArc = new MinorArc(circle, pt1, pt2); // Search for exact segment first foreach (MinorArc arc in figureMinorArcs) { if (arc.StructurallyEquals(candArc)) return arc; } return null; }
//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 LiveGeometry.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 GeometryTutorLib.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)))); }
public void AddMinorArc(MinorArc mArc) { minorArcs.Add(mArc); }