//
        // Perpendicular(Segment(A, B), Segment(C, D)), Angle(A, M, D), Angle(D, M, B) -> Congruent(Angle(A, M, D), Angle(D, M, B))
        //
        //                                            B
        //                                           /
        //                              C-----------/-----------D
        //                                         / M
        //                                        /
        //                                       A
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_IMPLY_CONGRUENT_ADJACENT_ANGLES;

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

            if (!(c is Angle) && !(c is Perpendicular))
            {
                return(newGrounded);
            }

            if (c is Angle)
            {
                Angle newAngle = c as Angle;

                // Find two candidate lines cut by the same transversal
                foreach (Perpendicular perp in candPerpendicular)
                {
                    foreach (Angle oldAngle in candAngles)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(perp, oldAngle, newAngle));
                    }
                }

                candAngles.Add(newAngle);
            }
            else if (c is Perpendicular)
            {
                Perpendicular newPerpendicular = c as Perpendicular;

                // Avoid generating if the situation is:
                //
                //   |
                //   |
                //   |_
                //   |_|_________
                //
                if (newPerpendicular.StandsOnEndpoint())
                {
                    return(newGrounded);
                }

                for (int i = 0; i < candAngles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candAngles.Count; j++)
                    {
                        newGrounded.AddRange(CheckAndGeneratePerpendicularImplyCongruentAdjacent(newPerpendicular, candAngles[i], candAngles[j]));
                    }
                }

                candPerpendicular.Add(newPerpendicular);
            }

            return(newGrounded);
        }
Example #2
0
        //
        // Perpendicular(B, Segment(A, B), Segment(B, C)) -> RightAngle(), RightAngle()
        //
        private static List <EdgeAggregator> InstantiateFromPerpendicular(GroundedClause original, Perpendicular perp)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();
            List <GroundedClause> antecedent  = new List <GroundedClause>();

            antecedent.Add(original);

            //          top
            //           |
            //           |_
            //           |_|____ right
            if (perp.StandsOnEndpoint())
            {
                Point top   = perp.lhs.OtherPoint(perp.intersect);
                Point right = perp.rhs.OtherPoint(perp.intersect);

                Strengthened streng = new Strengthened(new Angle(top, perp.intersect, right), new RightAngle(top, perp.intersect, right));

                newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            else if (perp.StandsOn())
            {
                Point top    = perp.lhs.Point1;
                Point center = perp.intersect;
                Point left   = perp.rhs.Point1;
                Point right  = perp.rhs.Point2;
                if (perp.lhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left  = perp.lhs.Point1;
                    right = perp.lhs.Point2;
                    top   = perp.rhs.OtherPoint(perp.intersect);
                }
                else if (perp.rhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left  = perp.rhs.Point1;
                    right = perp.rhs.Point2;
                    top   = perp.lhs.OtherPoint(perp.intersect);
                }
                else
                {
                    return(newGrounded);
                }

                Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened topLeft  = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            //           |
            //           |
            //         bottom
            else if (perp.Crossing())
            {
                Point top    = perp.lhs.Point1;
                Point bottom = perp.lhs.Point2;
                Point center = perp.intersect;
                Point left   = perp.rhs.Point1;
                Point right  = perp.rhs.Point2;

                Strengthened topRight    = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened bottomRight = new Strengthened(new Angle(right, center, bottom), new RightAngle(right, center, bottom));
                Strengthened bottomLeft  = new Strengthened(new Angle(left, center, bottom), new RightAngle(left, center, bottom));
                Strengthened topLeft     = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomLeft, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            else
            {
                return(newGrounded);
            }

            return(newGrounded);
        }