コード例 #1
0
        private static bool HandleRatioEquation(KnownMeasurementsAggregator known, SegmentRatioEquation theEq)
        {
            double topLeft     = known.GetSegmentLength(theEq.lhs.smallerSegment);
            double bottomLeft  = known.GetSegmentLength(theEq.lhs.largerSegment);
            double topRight    = known.GetSegmentLength(theEq.rhs.smallerSegment);
            double bottomRight = known.GetSegmentLength(theEq.rhs.largerSegment);

            int unknown = 0;

            if (topLeft <= 0)
            {
                unknown++;
            }
            if (bottomLeft <= 0)
            {
                unknown++;
            }
            if (topRight <= 0)
            {
                unknown++;
            }
            if (bottomRight <= 0)
            {
                unknown++;
            }
            if (unknown != 1)
            {
                return(false);
            }

            if (topLeft <= 0)
            {
                return(known.AddSegmentLength(theEq.lhs.smallerSegment, (topRight / bottomRight) * bottomLeft));
            }
            else if (bottomLeft <= 0)
            {
                return(known.AddSegmentLength(theEq.lhs.largerSegment, topLeft * (bottomRight / topRight)));
            }
            else if (topRight <= 0)
            {
                return(known.AddSegmentLength(theEq.rhs.smallerSegment, (topLeft / bottomLeft) * bottomRight));
            }
            else if (bottomRight <= 0)
            {
                return(known.AddSegmentLength(theEq.rhs.largerSegment, topRight * (bottomLeft / topLeft)));
            }
            else
            {
                return(false);
            }
        }
コード例 #2
0
ファイル: SSSSimilarity.cs プロジェクト: wcatykid/GeoShader
        //
        // In order for two triangles to be congruent, we require the following:
        //    Triangle(A, B, C), Triangle(D, E, F),
        //    SegmentRatio(Segment(A, B), Segment(D, E)),
        //    SegmentRatio(Segment(A, C), Segment(D, F)),
        //    SegmentRatio(Segment(B, C), Segment(E, F)) -> Congruent(Triangle(A, B, C), Triangle(D, E, F)),
        //                                                  Congruent(Angles(A, B, C), Angle(D, E, F)),
        //                                                  Congruent(Angles(C, A, B), Angle(F, D, E)),
        //                                                  Congruent(Angles(B, C, A), Angle(E, F, D)),
        //
        // Note: we need to figure out the proper order of the sides to guarantee congruence
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.SSS_SIMILARITY;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // If this is a new segment, check for congruent triangles with this new piece of information
            if (clause is SegmentRatioEquation)
            {
                SegmentRatioEquation newEq = clause as SegmentRatioEquation;

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        foreach (SegmentRatioEquation oldEq in candidateSegmentEquations)
                        {
                            newGrounded.AddRange(CheckForSSS(candidateTriangles[i], candidateTriangles[j], newEq, oldEq));
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidateSegmentEquations.Add(newEq);
            }
            // If this is a new triangle, check for triangles which may be congruent to this new triangle
            else if (clause is Triangle)
            {
                Triangle newTriangle = clause as Triangle;

                foreach (Triangle oldTriangle in candidateTriangles)
                {
                    for (int m = 0; m < candidateSegmentEquations.Count - 1; m++)
                    {
                        for (int n = m + 1; n < candidateSegmentEquations.Count; n++)
                        {
                            newGrounded.AddRange(CheckForSSS(newTriangle, oldTriangle, candidateSegmentEquations[m], candidateSegmentEquations[n]));
                        }
                    }
                }

                // Add this triangle to the list of possible clauses to unify later
                candidateTriangles.Add(newTriangle);
            }

            return(newGrounded);
        }
コード例 #3
0
        //
        // In order for two triangles to be Similar, we require the following:
        //    Triangle(A, B, C), Triangle(D, E, F),
        //    Proportional(Segment(A, B), Segment(D, E)),
        //    Congruent(Angle(A, B, C), Angle(D, E, F)),
        //    Proportional(Segment(B, C), Segment(E, F)) -> Similar(Triangle(A, B, C), Triangle(D, E, F)),
        //                                                  Proportional(Segment(A, C), Angle(D, F)),
        //                                                  Congruent(Angle(C, A, B), Angle(F, D, E)),
        //                                                  Congruent(Angle(B, C, A), Angle(E, F, D))
        //
        // Note: we need to figure out the proper order of the sides to guarantee similarity
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.SAS_SIMILARITY;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // If this is a new segment, check for Similar triangles with this new piece of information
            if (clause is SegmentRatioEquation)
            {
                SegmentRatioEquation newProp = clause as SegmentRatioEquation;

                // Check all combinations of triangles to see if they are Similar
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        foreach (CongruentAngles cas in candidateCongruentAngles)
                        {
                            newGrounded.AddRange(CollectAndCheckSAS(candidateTriangles[i], candidateTriangles[j], cas, newProp));
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidatePropSegmentEquations.Add(newProp);
            }
            else if (clause is CongruentAngles)
            {
                CongruentAngles newCas = clause as CongruentAngles;

                // Check all combinations of triangles to see if they are Similar
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        foreach (SegmentRatioEquation eq in candidatePropSegmentEquations)
                        {
                            newGrounded.AddRange(CollectAndCheckSAS(candidateTriangles[i], candidateTriangles[j], newCas, eq));
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidateCongruentAngles.Add(newCas);
            }

            // If this is a new triangle, check for triangles which may be Similar to this new triangle
            else if (clause is Triangle)
            {
                Triangle newTriangle = clause as Triangle;

                foreach (Triangle oldTriangle in candidateTriangles)
                {
                    foreach (CongruentAngles cas in candidateCongruentAngles)
                    {
                        foreach (SegmentRatioEquation eq in candidatePropSegmentEquations)
                        {
                            newGrounded.AddRange(CollectAndCheckSAS(newTriangle, oldTriangle, cas, eq));
                        }
                    }
                }

                // Add this triangle to the list of possible clauses to unify later
                candidateTriangles.Add(newTriangle);
            }

            return(newGrounded);
        }
コード例 #4
0
        //
        //
        //
        private static List <EdgeAggregator> CollectAndCheckSAS(Triangle ct1, Triangle ct2, CongruentAngles cas, SegmentRatioEquation sre)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Proportions must actually equate
            //if (!pss1.ProportionallyEquals(pss2)) return newGrounded;

            //// The smaller and larger segments of the proportionality must be distinct, respectively.
            //if (!pss1.IsDistinctFrom(pss2)) return newGrounded;

            // The proportional relationships need to link the given triangles
            if (!cas.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }
            if (!sre.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }
            //if (!pss1.LinksTriangles(ct1, ct2)) return newGrounded;
            //if (!pss2.LinksTriangles(ct1, ct2)) return newGrounded;

            // The smaller segments must belong to one triangle, same for larger segments.
            //if (!(ct1.HasSegment(pss1.smallerSegment) && ct1.HasSegment(pss2.smallerSegment) &&
            //      ct2.HasSegment(pss1.largerSegment) && ct2.HasSegment(pss2.largerSegment)) &&
            //    !(ct2.HasSegment(pss1.smallerSegment) && ct2.HasSegment(pss2.smallerSegment) &&
            //      ct1.HasSegment(pss1.largerSegment) && ct1.HasSegment(pss2.largerSegment)))
            //    return newGrounded;

            KeyValuePair <Segment, Segment> segsTri1 = sre.GetSegments(ct1);
            KeyValuePair <Segment, Segment> segsTri2 = sre.GetSegments(ct2);

            //Segment seg1Tri1 = ct1.GetSegment(pss1);
            //Segment seg2Tri1 = ct1.GetSegment(pss2);

            //Segment seg1Tri2 = ct2.GetSegment(pss1);
            //Segment seg2Tri2 = ct2.GetSegment(pss2);

            // Avoid redundant segments, if they arise
            if (segsTri1.Key.StructurallyEquals(segsTri1.Value))
            {
                return(newGrounded);
            }
            if (segsTri2.Key.StructurallyEquals(segsTri2.Value))
            {
                return(newGrounded);
            }
            //if (seg1Tri1.StructurallyEquals(seg2Tri1)) return newGrounded;
            //if (seg1Tri2.StructurallyEquals(seg2Tri2)) return newGrounded;

            Angle angleTri1 = ct1.AngleBelongs(cas);
            Angle angleTri2 = ct2.AngleBelongs(cas);

            // Check both triangles if this is the included angle; if it is, we have SAS
            if (!angleTri1.IsIncludedAngle(segsTri1.Key, segsTri1.Value))
            {
                return(newGrounded);
            }
            if (!angleTri2.IsIncludedAngle(segsTri2.Key, segsTri2.Value))
            {
                return(newGrounded);
            }

            //
            // Generate Similar Triangles
            //
            Point vertex1 = angleTri1.GetVertex();
            Point vertex2 = angleTri2.GetVertex();

            // Construct a list of pairs to return; this is the correspondence from triangle 1 to triangle 2
            List <KeyValuePair <Point, Point> > pairs = new List <KeyValuePair <Point, Point> >();

            // The vertices of the angles correspond
            pairs.Add(new KeyValuePair <Point, Point>(vertex1, vertex2));

            // For the segments, look at the congruences and select accordingly
            pairs.Add(new KeyValuePair <Point, Point>(segsTri1.Key.OtherPoint(vertex1), segsTri2.Key.OtherPoint(vertex2)));
            pairs.Add(new KeyValuePair <Point, Point>(segsTri1.Value.OtherPoint(vertex1), segsTri2.Value.OtherPoint(vertex2)));

            List <GroundedClause> simTriAntecedent = new List <GroundedClause>();

            simTriAntecedent.Add(ct1);
            simTriAntecedent.Add(ct2);
            simTriAntecedent.Add(cas);
            simTriAntecedent.Add(sre);

            newGrounded.AddRange(GenerateCorrespondingParts(pairs, simTriAntecedent, annotation));

            return(newGrounded);
        }
コード例 #5
0
ファイル: SSSSimilarity.cs プロジェクト: wcatykid/GeoShader
        //
        // Of all the congruent segment pairs, choose a subset of 3. Exhaustively check all; if they work, return the set.
        //
        private static List <EdgeAggregator> CheckForSSS(Triangle ct1, Triangle ct2, SegmentRatioEquation sre1, SegmentRatioEquation sre2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // The proportional relationships need to link the given triangles
            //
            if (!sre1.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }
            if (!sre2.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }

            //
            // Both equations must share a fraction (ratio)
            //
            if (!sre1.SharesRatio(sre2))
            {
                return(newGrounded);
            }

            //
            // Collect all of the applicable segments
            //
            SegmentRatio shared = sre1.GetSharedRatio(sre2);
            SegmentRatio other1 = sre1.GetOtherRatio(shared);
            SegmentRatio other2 = sre2.GetOtherRatio(shared);

            Segment seg1Tri1 = ct1.GetSegment(shared);
            Segment seg2Tri1 = ct1.GetSegment(other1);
            Segment seg3Tri1 = ct1.GetSegment(other2);

            if (seg1Tri1 == null || seg2Tri1 == null || seg3Tri1 == null)
            {
                return(newGrounded);
            }

            Segment seg1Tri2 = ct2.GetSegment(shared);
            Segment seg2Tri2 = ct2.GetSegment(other1);
            Segment seg3Tri2 = ct2.GetSegment(other2);

            if (seg1Tri2 == null || seg2Tri2 == null || seg3Tri2 == null)
            {
                return(newGrounded);
            }

            // Avoid redundant segments, if they arise
            if (seg1Tri1.StructurallyEquals(seg2Tri1) || seg1Tri1.StructurallyEquals(seg3Tri1) || seg2Tri1.StructurallyEquals(seg3Tri1))
            {
                return(newGrounded);
            }
            if (seg1Tri2.StructurallyEquals(seg2Tri2) || seg1Tri2.StructurallyEquals(seg3Tri2) || seg2Tri2.StructurallyEquals(seg3Tri2))
            {
                return(newGrounded);
            }

            //
            // Collect the corresponding points
            //
            List <KeyValuePair <Point, Point> > pointPairs = new List <KeyValuePair <Point, Point> >();

            pointPairs.Add(new KeyValuePair <Point, Point>(seg1Tri1.SharedVertex(seg2Tri1), seg1Tri2.SharedVertex(seg2Tri2)));
            pointPairs.Add(new KeyValuePair <Point, Point>(seg1Tri1.SharedVertex(seg3Tri1), seg1Tri2.SharedVertex(seg3Tri2)));
            pointPairs.Add(new KeyValuePair <Point, Point>(seg2Tri1.SharedVertex(seg3Tri1), seg2Tri2.SharedVertex(seg3Tri2)));

            List <GroundedClause> simTriAntecedent = new List <GroundedClause>();

            simTriAntecedent.Add(ct1);
            simTriAntecedent.Add(ct2);
            simTriAntecedent.Add(sre1);
            simTriAntecedent.Add(sre2);

            newGrounded.AddRange(SASSimilarity.GenerateCorrespondingParts(pointPairs, simTriAntecedent, annotation));

            return(newGrounded);
        }