예제 #1
0
        public static Figure ConstructDefaultShape(ShapeType type)
        {
            switch (type)
            {
            case ShapeType.TRIANGLE:               return(Triangle.ConstructDefaultTriangle());

            case ShapeType.ISOSCELES_TRIANGLE:     return(IsoscelesTriangle.ConstructDefaultIsoscelesTriangle());

            case ShapeType.RIGHT_TRIANGLE:         return(RightTriangle.ConstructDefaultRightTriangle());

            case ShapeType.EQUILATERAL_TRIANGLE:   return(EquilateralTriangle.ConstructDefaultEquilateralTriangle());

            case ShapeType.KITE:                   return(Kite.ConstructDefaultKite());

            case ShapeType.QUADRILATERAL:          return(Quadrilateral.ConstructDefaultQuadrilateral());

            case ShapeType.TRAPEZOID:              return(Trapezoid.ConstructDefaultTrapezoid());

            case ShapeType.ISO_TRAPEZOID:          return(IsoscelesTrapezoid.ConstructDefaultIsoscelesTrapezoid());

            case ShapeType.PARALLELOGRAM:          return(Parallelogram.ConstructDefaultParallelogram());

            case ShapeType.RECTANGLE:              return(Rectangle.ConstructDefaultRectangle());

            case ShapeType.RHOMBUS:                return(Rhombus.ConstructDefaultRhombus());

            case ShapeType.SQUARE:                 return(Square.ConstructDefaultSquare());

            case ShapeType.CIRCLE:                 return(Circle.ConstructDefaultCircle());

            case ShapeType.SECTOR:                 return(Sector.ConstructDefaultSector());
            }

            return(null);
        }
예제 #2
0
        //
        // Is this triangle encased in the given, larger triangle.
        // That is, two sides are defined by the larger triangle and one side by the altitude
        //
        public bool IsDefinedBy(RightTriangle rt, Altitude altitude)
        {
            // The opposite side of the smaller triangle has to be a side of the larger triangle.
            if (!rt.HasSegment(this.GetOppositeSide(this.rightAngle)))
            {
                return(false);
            }

            // The smaller triangle's right angle must have a ray collinear with the altitude segment
            Segment altSegment = null;

            if (this.rightAngle.ray1.IsCollinearWith(altitude.segment))
            {
                altSegment = this.rightAngle.ray1;
            }
            else if (this.rightAngle.ray2.IsCollinearWith(altitude.segment))
            {
                altSegment = this.rightAngle.ray2;
            }
            if (altSegment == null)
            {
                return(false);
            }

            // The last segment needs to be collinear with a side of the larger triangle
            return(rt.LiesOn(this.rightAngle.OtherRayEquates(altSegment)));
        }
예제 #3
0
        public new static List <FigSynthProblem> SubtractShape(Figure outerShape, List <Connection> conns, List <Point> points)
        {
            List <Triangle> tris = Triangle.GetTrianglesFromPoints(points);

            List <FigSynthProblem> composed = new List <FigSynthProblem>();

            foreach (Triangle tri in tris)
            {
                // Only create right triangles that are NOT the outershape.
                if (tri.isRightTriangle() && !tri.StructurallyEquals(outerShape))
                {
                    RightTriangle rTri = new RightTriangle(tri);

                    SubtractionSynth subSynth = new SubtractionSynth(outerShape, rTri);

                    try
                    {
                        subSynth.SetOpenRegions(FigSynthProblem.AcquireOpenAtomicRegions(conns, rTri.points, rTri));
                        composed.Add(subSynth);
                    }
                    catch (Exception) { }
                }
            }

            return(FigSynthProblem.RemoveSymmetric(composed));
        }
예제 #4
0
        public override bool Equals(Object obj)
        {
            RightTriangle triangle = obj as RightTriangle;

            if (triangle == null)
            {
                return(false);
            }
            return(base.Equals(obj));
        }
예제 #5
0
        //
        // Is this triangle encased in the given, larger triangle.
        // That is, two sides are defined by the larger triangle and one side by the altitude
        //
        public bool IsDefinedBy(RightTriangle rt, Altitude altitude)
        {
            // The opposite side of the smaller triangle has to be a side of the larger triangle.
            if (!rt.HasSegment(this.GetOppositeSide(this.rightAngle))) return false;

            // The smaller triangle's right angle must have a ray collinear with the altitude segment
            Segment altSegment = null;
            if (this.rightAngle.ray1.IsCollinearWith(altitude.segment))
            {
                altSegment = this.rightAngle.ray1;
            }
            else if (this.rightAngle.ray2.IsCollinearWith(altitude.segment))
            {
                altSegment = this.rightAngle.ray2;
            }
            if (altSegment == null) return false;

            // The last segment needs to be collinear with a side of the larger triangle
            return rt.LiesOn(this.rightAngle.OtherRayEquates(altSegment));
        }
예제 #6
0
        private List<KeyValuePair<Segment, double>> CalcSidesHypotenuseUnknown(RightTriangle tri, Angle knownAngle, double knownAngleVal, Segment knownSide, double sideVal)
        {
            List<KeyValuePair<Segment, double>> pairs = new List<KeyValuePair<Segment, double>>();

            Segment hypotenuse = tri.GetHypotenuse();
            Segment oppSideOfAngle = tri.GetOppositeSide(knownAngle);
            Segment adjacent = knownAngle.OtherRay(hypotenuse);

            if (oppSideOfAngle.StructurallyEquals(knownSide))
            {
                double adjVal = sideVal / Math.Tan(Angle.toRadians(knownAngleVal));

                pairs.Add(new KeyValuePair<Segment, double>(adjacent, adjVal));
                pairs.Add(new KeyValuePair<Segment, double>(hypotenuse, Math.Sqrt(sideVal * sideVal + adjVal * adjVal)));
            }
            else if (adjacent.StructurallyEquals(knownSide))
            {
                double oppVal = sideVal * Math.Tan(Angle.toRadians(knownAngleVal));

                pairs.Add(new KeyValuePair<Segment, double>(oppSideOfAngle, oppVal));
                pairs.Add(new KeyValuePair<Segment, double>(hypotenuse, Math.Sqrt(sideVal * sideVal + oppVal * oppVal)));
            }

            return pairs;
        }
예제 #7
0
        //
        //
        // Given 1 side of a right triangle and an angle, calculate the other 2 sides.
        //
        //
        private List<KeyValuePair<Segment, double>> CalcSidesHypotenuseKnown(RightTriangle tri, Angle knownAngle, double knownAngleVal, Segment hypotenuse, double hypotVal)
        {
            List<KeyValuePair<Segment, double>> pairs = new List<KeyValuePair<Segment, double>>();

            double oppSideLength = hypotVal * Math.Sin(Angle.toRadians(knownAngleVal));
            pairs.Add(new KeyValuePair<Segment,double>(tri.GetOppositeSide(knownAngle), oppSideLength));

            double adjSideLength = hypotVal * Math.Cos(Angle.toRadians(knownAngleVal));
            pairs.Add(new KeyValuePair<Segment, double>(knownAngle.OtherRay(hypotenuse), adjSideLength));

            return pairs;
        }
예제 #8
0
        private List<KeyValuePair<Segment, double>> CalcSides(RightTriangle tri, Angle rightAngle, Angle knownAngle, double knownAngleVal, Segment knownSeg, double knownSegVal)
        {
            //
            // Determine the nature of the known Segment w.r.t. to the known angle.
            //
            Segment hypotenuse = tri.GetHypotenuse();

            // Hypotenuse known
            if (knownSeg.StructurallyEquals(hypotenuse))
            {
                return CalcSidesHypotenuseKnown(tri, knownAngle, knownAngleVal, hypotenuse, knownSegVal);
            }
            else
            {
                return CalcSidesHypotenuseUnknown(tri, knownAngle, knownAngleVal, knownSeg, knownSegVal);
            }
        }
예제 #9
0
        public List<KeyValuePair<Segment, double>> RightTriangleTrigApplies(Area_Based_Analyses.KnownMeasurementsAggregator known)
        {
            List<KeyValuePair<Segment, double>> pairs = new List<KeyValuePair<Segment, double>>();

            if (!(this is RightTriangle) && !this.provenRight) return pairs;

            //
            // Make a right
            //
            RightTriangle rightTri = new RightTriangle(this);
            Angle otherAngle1, otherAngle2;
            Angle rightAngle = rightTri.rightAngle;
            rightTri.GetOtherAngles(rightAngle, out otherAngle1, out otherAngle2);

            double angleMeasure1 = known.GetAngleMeasure(otherAngle1);
            double angleMeasure2 = known.GetAngleMeasure(otherAngle2);

            // Need to know one side length
            if (angleMeasure1 < 0 && angleMeasure2 < 0) return pairs;

            double knownSegVal = -1;
            Segment knownSeg = null;
            foreach (Segment side in orderedSides)
            {
                knownSegVal = known.GetSegmentLength(side);
                if (knownSegVal > 0)
                {
                    knownSeg = side;
                    break;
                }
            }

            // Need to know one side length
            if (knownSegVal < 0) return pairs;

            // Need at least one measure.
            if (angleMeasure1 > 0) return CalcSides(rightTri, rightAngle, otherAngle1, angleMeasure1, knownSeg, knownSegVal);
            if (angleMeasure2 > 0) return CalcSides(rightTri, rightAngle, otherAngle2, angleMeasure2, knownSeg, knownSegVal);

            return pairs;
        }
        public static List<EdgeAggregator> InstantiateRight(RightTriangle rt, Altitude altitude, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The altitude must connect the vertex defining the right angle and the opposite side.
            if (!altitude.segment.HasPoint(rt.rightAngle.GetVertex())) return newGrounded;

            // The other point of the altitude must lie on the opposite side of the triangle
            Point altPointOppRightAngle = altitude.segment.OtherPoint(rt.rightAngle.GetVertex());

            Segment oppositeSide = rt.GetOppositeSide(rt.rightAngle);

            if (!Segment.Between(altPointOppRightAngle, oppositeSide.Point1, oppositeSide.Point2)) return newGrounded;

            //
            // Find the two smaller right triangles in the candidate list (which should be in the list at this point)
            //
            RightTriangle first = null;
            RightTriangle second = null;
            foreach (RightTriangle smallerRT in candRightTriangles)
            {
                if (smallerRT.IsDefinedBy(rt, altitude))
                {
                    if (first == null)
                    {
                        first = smallerRT;
                    }
                    else
                    {
                        second = smallerRT;
                        break;
                    }
                }
            }

            // CTA: We did not check to see points aligned, but these are the original triangles from the figure
            GeometricSimilarTriangles gsts1 = new GeometricSimilarTriangles(rt, first);
            GeometricSimilarTriangles gsts2 = new GeometricSimilarTriangles(rt, second);
            GeometricSimilarTriangles gsts3 = new GeometricSimilarTriangles(first, second);

            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(original);
            antecedent.Add(altitude);

            newGrounded.Add(new EdgeAggregator(antecedent, gsts1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, gsts2, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, gsts3, annotation));

            return newGrounded;
        }
예제 #11
0
        private static List<EdgeAggregator> InstantiateFromRightTriangle(RightTriangle rightTri, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Strengthen the old triangle to a right triangle
            Strengthened newStrengthened = new Strengthened(rightTri.rightAngle, new RightAngle(rightTri.rightAngle));

            // Hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(original);

            newGrounded.Add(new EdgeAggregator(antecedent, newStrengthened, annotation));

            return newGrounded;
        }
예제 #12
0
 private static List<EdgeAggregator> ReconfigureAndCheck(RightTriangle rt1,  Strengthened streng, CongruentSegments css1, CongruentSegments css2)
 {
     return CollectAndCheckHL(rt1, streng.strengthened as RightTriangle, css1, css2, rt1, streng);
 }
예제 #13
0
 //
 // Acquires all of the applicable congruent segments; then checks HL
 //
 private static List<EdgeAggregator> ReconfigureAndCheck(RightTriangle rt1, RightTriangle rt2, CongruentSegments css1, CongruentSegments css2)
 {
     return CollectAndCheckHL(rt1, rt2, css1, css2, rt1, rt2);
 }
예제 #14
0
        //
        // Acquires all of the applicable congruent segments; then checks HL
        //
        private static List<EdgeAggregator> CollectAndCheckHL(RightTriangle rt1, RightTriangle rt2, 
                                                                                                  CongruentSegments css1, CongruentSegments css2,
                                                                                                  GroundedClause original1, GroundedClause original2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The Congruence pairs must relate the two triangles
            if (!css1.LinksTriangles(rt1, rt2) || !css2.LinksTriangles(rt1, rt2)) return newGrounded;

            // One of the congruence pairs must relate the hypotenuses
            Segment hypotenuse1 = rt1.OtherSide(rt1.rightAngle);
            Segment hypotenuse2 = rt2.OtherSide(rt2.rightAngle);

            // Determine the specific congruence pair that relates the hypotenuses
            CongruentSegments hypotenuseCongruence = null;
            CongruentSegments nonHypotenuseCongruence = null;
            if (css1.HasSegment(hypotenuse1) && css1.HasSegment(hypotenuse2))
            {
                hypotenuseCongruence = css1;
                nonHypotenuseCongruence = css2;
            }
            else if (css2.HasSegment(hypotenuse1) && css2.HasSegment(hypotenuse2))
            {
                hypotenuseCongruence = css2;
                nonHypotenuseCongruence = css1;
            }
            else return newGrounded;

            // Sanity check that the non hypotenuse congruence pair does not contain hypotenuse
            if (nonHypotenuseCongruence.HasSegment(hypotenuse1) || nonHypotenuseCongruence.HasSegment(hypotenuse2)) return newGrounded;

            //
            // We now have a hypotenuse leg situation; acquire the point-to-point congruence mapping
            //
            List<Point> triangleOne = new List<Point>();
            List<Point> triangleTwo = new List<Point>();

            // Right angle vertices correspond
            triangleOne.Add(rt1.rightAngle.GetVertex());
            triangleTwo.Add(rt2.rightAngle.GetVertex());

            Point nonRightVertexRt1 = rt1.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse1);
            Point nonRightVertexRt2 = rt2.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse2);

            triangleOne.Add(nonRightVertexRt1);
            triangleTwo.Add(nonRightVertexRt2);

            triangleOne.Add(hypotenuse1.OtherPoint(nonRightVertexRt1));
            triangleTwo.Add(hypotenuse2.OtherPoint(nonRightVertexRt2));

            //
            // Construct the new deduced relationships
            //
            GeometricCongruentTriangles ccts = new GeometricCongruentTriangles(new Triangle(triangleOne),
                                                                               new Triangle(triangleTwo));

            // Hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(original1);
            antecedent.Add(original2);
            antecedent.Add(css1);
            antecedent.Add(css2);

            newGrounded.Add(new EdgeAggregator(antecedent, ccts, annotation));

            // Add all the corresponding parts as new congruent clauses
            newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(ccts, triangleOne, triangleTwo));

            return newGrounded;
        }
예제 #15
0
        public static new List<FigSynthProblem> SubtractShape(Figure outerShape, List<Connection> conns, List<Point> points)
        {
            List<Triangle> tris = Triangle.GetTrianglesFromPoints(points);

            List<FigSynthProblem> composed = new List<FigSynthProblem>();
            foreach (Triangle tri in tris)
            {
                // Only create right triangles that are NOT the outershape.
                if (tri.isRightTriangle() && !tri.StructurallyEquals(outerShape))
                {
                    RightTriangle rTri = new RightTriangle(tri);

                    SubtractionSynth subSynth = new SubtractionSynth(outerShape, rTri);

                    try
                    {
                        subSynth.SetOpenRegions(FigSynthProblem.AcquireOpenAtomicRegions(conns, rTri.points, rTri));
                        composed.Add(subSynth);
                    }
                    catch (Exception) { }

                }
            }

            return FigSynthProblem.RemoveSymmetric(composed);
        }