//--------------------------------------------------------------------------------------------------

        public static bool Solve(Sketch sketch, bool precise)
        {
            var solver = new SketchConstraintSolver();
            var result = solver._Solve(sketch.Points, sketch.Segments, sketch.Constraints, precise) == Result.Success;

            //Debug.WriteLine("Sketch constraints " + (result ? "solved successful." : "have no solution."));
            return(result);
        }
Esempio n. 2
0
        //--------------------------------------------------------------------------------------------------

        public abstract bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver);
Esempio n. 3
0
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var lineSegment1 = segments[Segments[0]] as SketchSegmentLine;

            if (lineSegment1 == null)
            {
                return(false);
            }
            var lineSegment2 = segments[Segments[1]] as SketchSegmentLine;

            if (lineSegment2 == null)
            {
                return(false);
            }

            // Find intersetion point to sort line directions
            var lin2d1 = lineSegment1.GetLine(points);
            var lin2d2 = lineSegment2.GetLine(points);

            if (lin2d1 == null || lin2d2 == null)
            {
                return(false);
            }

            var intersection = new IntAna2d_AnaIntersection(lin2d1, lin2d2);

            if (!intersection.IsDone() || intersection.IdenticalElements() || intersection.ParallelElements() || intersection.NbPoints() == 0)
            {
                return(false);
            }

            var  intPnt   = intersection.Point(1).Value();
            bool reverse1 = intPnt.SquareDistance(lin2d1.Location()) > intPnt.SquareDistance(lin2d1.Location().Translated(lin2d1.Direction().ToVec()));
            bool reverse2 = intPnt.SquareDistance(lin2d2.Location()) > intPnt.SquareDistance(lin2d2.Location().Translated(lin2d2.Direction().ToVec()));

            // Create constraint
            bool valid = true;
            var  con   = new Constraint {
                Type = ConstraintType.InternalAngle
            };

            valid &= solver.SetLine(ref con.Line1, lineSegment1.Points[reverse1 ? 1 : 0], lineSegment1.Points[reverse1 ? 0 : 1], false, false);
            valid &= solver.SetLine(ref con.Line2, lineSegment2.Points[reverse2 ? 1 : 0], lineSegment2.Points[reverse2 ? 0 : 1], false, false);
            valid &= solver.SetParameter(out con.Parameter, Angle.ToRad(), true);

            if (valid)
            {
                solver.AddConstraint(con);
            }
            return(valid);
        }
Esempio n. 4
0
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var lineSegment = segments[Segments[0]] as SketchSegmentLine;

            if (lineSegment == null)
            {
                return(false);
            }

            var con = new Constraint {
                Type = ConstraintType.Horizontal
            };

            bool valid = solver.SetLine(ref con.Line1, lineSegment.Points[0], lineSegment.Points[1], false, false);

            if (valid)
            {
                solver.AddConstraint(con);
            }
            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            bool valid = true;

            var con = new Constraint {
                Type = ConstraintType.PointHorizontalDistance
            };

            valid &= solver.SetPoint(ref con.Point1, Points[0], false);
            valid &= solver.SetParameter(out con.Parameter, Distance, true);

            if (valid)
            {
                solver.AddConstraint(con);
            }

            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var lineSegment1 = segments[Segments[0]] as SketchSegmentLine;

            if (lineSegment1 == null)
            {
                return(false);
            }
            var lineSegment2 = segments[Segments[1]] as SketchSegmentLine;

            if (lineSegment2 == null)
            {
                return(false);
            }

            var con = new Constraint {
                Type = ConstraintType.Perpendicular
            };

            bool valid = true;

            valid &= solver.SetLine(ref con.Line1, lineSegment1.Points[0], lineSegment1.Points[1], false, false);
            valid &= solver.SetLine(ref con.Line2, lineSegment2.Points[0], lineSegment2.Points[1], false, false);

            if (valid)
            {
                solver.AddConstraint(con);
            }
            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var lineSegment = segments[Segments[0]] as SketchSegmentLine;

            if (lineSegment == null)
            {
                return(false);
            }

            var con = new Constraint {
                Type = ConstraintType.LineLength
            };

            bool valid = Length > 0;

            valid &= solver.SetParameter(out con.Parameter, Length, true);
            valid &= solver.SetLine(ref con.Line1, lineSegment.Points[0], lineSegment.Points[1], false, false);

            if (valid)
            {
                solver.AddConstraint(con);
            }
            return(valid);
        }
Esempio n. 8
0
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var constraints = new List <Constraint>();

            SketchSegmentLine lineSegment;
            SketchSegment     tangentToSeg;

            if (segments[Segments[0]] is SketchSegmentLine lineSeg0)
            {
                lineSegment  = lineSeg0;
                tangentToSeg = segments[Segments[1]];
            }
            else
            {
                lineSegment  = segments[Segments[1]] as SketchSegmentLine;
                tangentToSeg = segments[Segments[0]];
            }
            if (lineSegment == null)
            {
                return(false);
            }

            bool       valid = true;
            Constraint con;

            if (tangentToSeg is SketchSegmentCircle || tangentToSeg is SketchSegmentArc)
            {
                con = new Constraint {
                    Type = ConstraintType.TangentToCircle
                };
                valid &= solver.SetLine(ref con.Line1, lineSegment.Points[0], lineSegment.Points[1], false, false);
                valid &= solver.SetCircle(ref con.Circle1, tangentToSeg, constraints, points, false, false);
                constraints.Add(con);
            }
            else
            {
                return(false);
            }

            if (valid)
            {
                constraints.ForEach(solver.AddConstraint);
            }

            return(valid);
        }
Esempio n. 9
0
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            switch (Target)
            {
            case TargetType.Point:
                solver.FixPoint(Points[0]);
                return(true);

            case TargetType.Segment:
                foreach (var point in segments[Segments[0]].Points)
                {
                    solver.FixPoint(point);
                }
                return(true);
            }

            return(false);
        }
Esempio n. 10
0
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            if (Radius <= 0)
            {
                return(false);
            }

            List <Constraint> constraints = new List <Constraint>();
            bool valid = true;

            if (segments[Segments[0]] is SketchSegmentCircle circleSegment)
            {
                // Circle
                var con = new Constraint {
                    Type = ConstraintType.CircleRadius
                };
                valid &= solver.SetCircle(ref con.Circle1, circleSegment, constraints, points, false, false);
                valid &= solver.SetParameter(out con.Parameter, Radius, true);
                constraints.Add(con);
            }
            else if (segments[Segments[0]] is SketchSegmentArc arcRimSegment)
            {
                // Arc Rim
                var con = new Constraint {
                    Type = ConstraintType.CircleRadius
                };
                valid &= solver.SetCircle(ref con.Circle1, arcRimSegment, constraints, points, false, false);
                valid &= solver.SetParameter(out con.Parameter, Radius, true);
                constraints.Add(con);
            }

            if (valid)
            {
                constraints.ForEach(solver.AddConstraint);
            }
            return(true);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var constraints = new List <Constraint>();
            var con         = new Constraint {
                Type = ConstraintType.ConcentricCircles
            };

            bool valid = true;

            valid &= solver.SetCircle(ref con.Circle1, segments[Segments[0]], constraints, points, false, true);
            valid &= solver.SetCircle(ref con.Circle2, segments[Segments[1]], constraints, points, false, true);

            if (valid)
            {
                constraints.ForEach(solver.AddConstraint);
                solver.AddConstraint(con);
            }
            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            if (segments[Segments[0]] is SketchSegmentLine lineSegment1)
            {
                var lineSegment2 = segments[Segments[1]] as SketchSegmentLine;
                if (lineSegment2 == null)
                {
                    return(false);
                }

                var con = new Constraint {
                    Type = ConstraintType.EqualLength
                };

                bool valid = true;
                valid &= solver.SetLine(ref con.Line1, lineSegment1.Points[0], lineSegment1.Points[1], false, false);
                valid &= solver.SetLine(ref con.Line2, lineSegment2.Points[0], lineSegment2.Points[1], false, false);

                if (valid)
                {
                    solver.AddConstraint(con);
                }
                return(valid);
            }

            if (segments[Segments[0]] is SketchSegmentCircle circleSegment1)
            {
                List <Constraint> constraints = new List <Constraint>();

                var circleSegment2 = segments[Segments[1]] as SketchSegmentCircle;
                if (circleSegment2 == null)
                {
                    return(false);
                }
                bool valid = true;

                var con = new Constraint {
                    Type = ConstraintType.EqualRadiusCircles
                };
                valid &= solver.SetCircle(ref con.Circle1, circleSegment1, constraints, points, true, false);
                valid &= solver.SetCircle(ref con.Circle2, circleSegment2, constraints, points, true, false);
                constraints.Add(con);

                if (valid)
                {
                    constraints.ForEach(solver.AddConstraint);
                }
                return(valid);
            }
            return(false);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            bool valid = false;

            if (segments[Segments[0]] is SketchSegmentLine)
            {
                var lineSegment = (SketchSegmentLine)segments[Segments[0]];

                var con = new Constraint {
                    Type = ConstraintType.PointOnLineMidpoint
                };
                valid  = solver.SetLine(ref con.Line1, lineSegment.Points[0], lineSegment.Points[1], true, true);
                valid &= solver.SetPoint(ref con.Point1, Points[0], false);

                if (valid)
                {
                    solver.AddConstraint(con);
                }
            }

            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            bool valid = false;

            if (segments[Segments[0]] is SketchSegmentLine)
            {
                var lineSegment = (SketchSegmentLine)segments[Segments[0]];

                var con = new Constraint {
                    Type = ConstraintType.PointOnLine
                };
                valid  = solver.SetLine(ref con.Line1, lineSegment.Points[0], lineSegment.Points[1], true, true);
                valid &= solver.SetPoint(ref con.Point1, Points[0], false);

                if (valid)
                {
                    solver.AddConstraint(con);
                }
            }
            else if (segments[Segments[0]] is SketchSegmentCircle)
            {
                List <Constraint> constraints = new List <Constraint>();

                var circleSegment = (SketchSegmentCircle)segments[Segments[0]];

                var con = new Constraint {
                    Type = ConstraintType.PointOnCircle
                };
                valid  = solver.SetCircle(ref con.Circle1, circleSegment, constraints, points, true, false);
                valid &= solver.SetPoint(ref con.Point1, Points[0], false);
                constraints.Add(con);

                if (valid)
                {
                    constraints.ForEach(solver.AddConstraint);
                }
            }

            return(valid);
        }
        //--------------------------------------------------------------------------------------------------

        public override bool MakeConstraint(Dictionary <int, Pnt2d> points, Dictionary <int, SketchSegment> segments, SketchConstraintSolver solver)
        {
            var adjacentSegments = SketchUtils.GetSegmentsUsingPoint(segments, Points[0]).ToArray();

            if (adjacentSegments.Length != 2)
            {
                return(false);
            }

            // Prepare values
            int tan1p1 = -1, tan1p2 = -1;
            var bezier1 = segments[adjacentSegments[0]] as SketchSegmentBezier;

            if (bezier1 != null)
            {
                if (bezier1.Points[0] == Points[0])
                {
                    tan1p1 = bezier1.Points[0];
                    tan1p2 = bezier1.Points[1];
                }
                else
                {
                    tan1p1 = bezier1.Points[bezier1.Degree];
                    tan1p2 = bezier1.Points[bezier1.Degree - 1];
                }
            }

            int tan2p1 = -1, tan2p2 = 1;
            var bezier2 = segments[adjacentSegments[1]] as SketchSegmentBezier;

            if (bezier2 != null)
            {
                if (bezier2.Points[0] == Points[0])
                {
                    tan2p1 = bezier2.Points[0];
                    tan2p2 = bezier2.Points[1];
                }
                else
                {
                    tan2p1 = bezier2.Points[bezier2.Degree];
                    tan2p2 = bezier2.Points[bezier2.Degree - 1];
                }
            }

            if (bezier1 != null && bezier2 != null)
            {
                // *** Bezier-Bezier ***
                var con = new Constraint {
                    Type = ConstraintType.Colinear
                };
                if (!solver.SetLine(ref con.Line1, tan1p1, tan1p2, true, false) ||
                    !solver.SetLine(ref con.Line2, tan2p1, tan2p2, true, false))
                {
                    return(false);
                }
                solver.AddConstraint(con);

                if (Symmetric)
                {
                    con.Type = ConstraintType.EqualLength;
                    solver.AddConstraint(con);
                }
                return(true);
            }

            var line = segments[adjacentSegments[0]] as SketchSegmentLine ?? segments[adjacentSegments[1]] as SketchSegmentLine;

            if (line != null && (bezier1 != null || bezier2 != null))
            {
                // *** Bezier-Line ***
                var con = new Constraint {
                    Type = ConstraintType.Colinear
                };
                if (!solver.SetLine(ref con.Line1, bezier1 != null ? tan1p1 : tan2p1, bezier1 != null ? tan1p2 : tan2p2, true, false) ||
                    !solver.SetLine(ref con.Line2, line.StartPoint, line.EndPoint, true, true))
                {
                    return(false);
                }
                solver.AddConstraint(con);
                return(true);
            }

            var arc = segments[adjacentSegments[0]] as SketchSegmentArc ?? segments[adjacentSegments[1]] as SketchSegmentArc;

            if (arc != null && (bezier1 != null || bezier2 != null))
            {
                // *** Bezier-Arc ***
                var constraints = new List <Constraint>();
                var con         = new Constraint {
                    Type = ConstraintType.TangentToCircle
                };
                if (!solver.SetLine(ref con.Line1, bezier1 != null ? tan1p1 : tan2p1, bezier1 != null ? tan1p2 : tan2p2, true, false) ||
                    !solver.SetCircle(ref con.Circle1, arc, constraints, points, true, true))
                {
                    return(false);
                }
                constraints.ForEach(c => solver.AddConstraint(c));
                solver.AddConstraint(con);
                return(true);
            }

            return(false);
        }