public void ParallelTest() { var parametersList = new List <double> { 0, 0, 3, 0, 0, 10, -5, 5 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new ParallelRef { L1 = new RefLine(6, 7, 0, 1), L2 = new RefLine(2, 3, 4, 5) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 0, constraints, 0); Assert.IsTrue(error == 1, "Invalid solution"); solver = new BFGSSolver(); error = solver.SolveRef(ref parameters, 1, constraints, 0); Assert.IsTrue(error == 0, "Invalid solution"); //parameters[0] = -3.49999 Assert.IsTrue(Math.Abs(parameters[0] + 3.4999) < 0.001); }
public void RectangleTest() { var parametersList = new List <double> { 1, 4, 6, 1, 6, 5, 1, 1 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new ParallelRef { L1 = new RefLine(4, 5, 0, 1), L2 = new RefLine(6, 7, 2, 3) }); constraints.Add(new ParallelRef { L1 = new RefLine(2, 3, 4, 5), L2 = new RefLine(0, 1, 6, 7) }); constraints.Add(new PerpendicularRef { L1 = new RefLine(4, 5, 0, 1), L2 = new RefLine(0, 1, 6, 7) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 0, constraints, 0); Assert.IsTrue(error == 1, "Invalid solution"); solver = new BFGSSolver(); error = solver.SolveRef(ref parameters, 2, constraints, 0); Assert.IsTrue(error == 0, "Invalid solution"); Assert.IsTrue(Math.Abs(parameters[0] - 1) < 0.001); Assert.IsTrue(Math.Abs(parameters[1] - 5) < 0.001); }
public void ParallelToYAxisTest() { var parametersList = new List <double> { 1, 0, 1, 4, 5, 0, 5, 13 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); var line1 = new RefLine(0, 1, 2, 3); var line2 = new RefLine(4, 5, 6, 7); constraints.Add(new ParallelRef { L1 = line1, L2 = line2 }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 0, constraints, 0); Assert.IsTrue(error == 0, "Invalid parallel solution"); var m1 = LineSlope(line1, parameters); var m2 = LineSlope(line2, parameters); Assert.IsTrue(double.IsPositiveInfinity(m1)); Assert.AreEqual(m1, m2); }
public void VerticalTest() { var parametersList = new List <double> { 3, 1, 4, 2 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new VerticalRef { L1 = new RefLine(0, 1, 2, 3) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 1, constraints, 0); Assert.IsTrue(error == 0, "Invalid horizontal solution"); Assert.IsTrue(Math.Abs(parameters[0] - 4) < 0.01, "invalid x axis values"); }
public void HorizontalDistanceToCenterTest() { var parametersList = new List <double> { 2, 2 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new HorizontalDistanceToCenterRef { P1 = new RefPoint(0, 1), Distance = 10 }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 2, constraints, 0); Assert.IsTrue(error == 0, "Invalid horizontal solution"); Assert.IsTrue(Math.Abs(parameters[0] - 10) < 0.01, "invalid x axis values"); }
public void PointOnLineTest() { var parametersList = new List <double> { 3, 1, 4, 2, 5, 2 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new PointOnLineRef { P1 = new RefPoint(0, 1), L1 = new RefLine(2, 3, 4, 5) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 2, constraints, 0); Assert.IsTrue(error == 0, "Invalid point on point solution"); Assert.IsTrue(Math.Abs(parameters[0] - 3) < 0.01, "invalid x axis value"); Assert.IsTrue(Math.Abs(parameters[1] - 2) < 0.01, "invalid y axis value"); }
public void PerpendicularTest() { var parametersList = new List <double> { 5, 3, 1, 1, 4, 1 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new PerpendicularRef { L1 = new RefLine(2, 3, 4, 5), L2 = new RefLine(0, 1, 4, 5) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 1, constraints, 0); Assert.IsTrue(error == 0, "Invalid perpendicular solution"); Assert.IsTrue(Math.Abs(parameters[0] - 4) < 0.0001); Assert.IsTrue(Math.Abs(parameters[1] - 3) < 0.0001); }
public void PerpendicularWithFixedPointTest() { var parametersList = new List <double> { 6, 8, 6, 3, 2, 6 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); constraints.Add(new PerpendicularRef { L1 = new RefLine(0, 1, 2, 3), L2 = new RefLine(0, 1, 4, 5) }); constraints.Add(new HorizontalDistanceToCenterRef { P1 = new RefPoint(0, 1), Distance = 2 }); constraints.Add(new VerticalDistanceToCenterRef { P1 = new RefPoint(0, 1), Distance = 2 }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, 6, constraints, 0); Assert.IsTrue(error == 0, "Invalid perpendicular solution"); var m1 = LineSlope(new RefLine(0, 1, 2, 3), parameters); var m2 = LineSlope(new RefLine(0, 1, 4, 5), parameters); Assert.IsTrue((m1 * m2 + 1) < 0.01, "invalid perpendicular values"); Assert.IsTrue(Math.Abs(parameters[0] - 2) < 0.0001, "invalid point values for Horizontal distance constraint"); Assert.IsTrue(Math.Abs(parameters[1] - 2) < 0.0001, "invalid point values for Vertical distance constraint"); }
public void ThreeRectanglesTest() { var parametersList = new List <double> { 2, 1, 5, 4, 8, 1, 11, 1, /*fixed points:*/ 7, -1, 2, 4, 8, 4, 11, 4 }; var parameters = new Vector(parametersList); var constraints = new ConstraintRefContainer(); /* first rectangle*/ constraints.Add(new ParallelRef { L1 = new RefLine(0, 1, 8, 9), L2 = new RefLine(10, 11, 2, 3) }); constraints.Add(new ParallelRef { L1 = new RefLine(10, 11, 0, 1), L2 = new RefLine(2, 3, 8, 9) }); constraints.Add(new PerpendicularRef { L1 = new RefLine(10, 11, 0, 1), L2 = new RefLine(0, 1, 8, 9) }); /*second rectangle*/ constraints.Add(new ParallelRef { L1 = new RefLine(2, 3, 12, 13), L2 = new RefLine(8, 9, 4, 5) }); constraints.Add(new ParallelRef { L1 = new RefLine(2, 3, 8, 9), L2 = new RefLine(12, 13, 4, 5) }); constraints.Add(new PerpendicularRef { L1 = new RefLine(2, 3, 8, 9), L2 = new RefLine(8, 9, 4, 5) }); /*third rectangle*/ constraints.Add(new ParallelRef { L1 = new RefLine(12, 13, 14, 15), L2 = new RefLine(4, 5, 6, 7) }); constraints.Add(new ParallelRef { L1 = new RefLine(12, 13, 4, 5), L2 = new RefLine(14, 15, 6, 7) }); constraints.Add(new PerpendicularRef { L1 = new RefLine(12, 13, 4, 5), L2 = new RefLine(4, 5, 6, 7) }); var solver = new BFGSSolver(); var error = solver.SolveRef(ref parameters, parameters.Count - 8, constraints, 0); Assert.IsTrue(error == 0, "Invalid parallel solution"); Assert.IsTrue(Math.Abs(parameters[1] + 1) < 0.001, "P0.y is not -1!"); Assert.IsTrue(Math.Abs(parameters[5] + 1) < 0.001, "P3.y is not -1!"); Assert.IsTrue(Math.Abs(parameters[7] + 1) < 0.001, "P4.y is not -1!"); Assert.IsTrue(Math.Abs(parameters[9] + 1) < 0.001, "P5.y is not -1!"); Assert.IsTrue(Math.Abs(parameters[0] - 2) < 0.001, "P0.x is not 7!"); Assert.IsTrue(Math.Abs(parameters[4] - 8) < 0.001, "P3.x is not 2!"); Assert.IsTrue(Math.Abs(parameters[6] - 11) < 0.001, "P4.x is not 8!"); Assert.IsTrue(Math.Abs(parameters[8] - 7) < 0.001, "P5.x is not 11!"); Assert.IsTrue(Math.Abs(parameters[2] - 7) < 0.001, "P2.x is not 7!"); Assert.IsTrue(Math.Abs(parameters[3] - 4) < 0.001, "P2.Y is not 4!"); }
public int Solve() { if (!_shapeList.Any() || !_constraints.Any()) { return(0); } // transform parameters var sketchNode = AutoGroupLogic.FindSketchNode(_document.Root[_shapeList.First()]); var axisAll = NodeBuilderUtils.GetTransformedAxis(new NodeBuilder(sketchNode)); var sketchAx2 = new gpAx2(axisAll.Location, axisAll.Direction); LoadParameters(sketchAx2); LoadConstraints(); if (SetConstraintsList.Size == 0) { return(0); } var freeParametersCount = 1; var maxFreeParametersCount = Parameters.Count - 2; var error = 1; var dfpSolver = new DFPSolver(); while (error == 1 && freeParametersCount <= maxFreeParametersCount) { error = dfpSolver.SolveRef(ref Parameters, freeParametersCount, ConstraintList, 1); freeParametersCount++; } Sketch2DSolver solver; if (error == 1) { var bfgsSolver = new BFGSSolver(); freeParametersCount = 1; while (error == 1 && freeParametersCount <= maxFreeParametersCount) { error = bfgsSolver.SolveRef(ref Parameters, freeParametersCount, ConstraintList, 1); freeParametersCount++; } solver = bfgsSolver; } else { solver = dfpSolver; } if (error == 0) { // update point position with the values returned by the solver int index = 0; foreach (var shape in ShapeToParamIndex.Keys) { //if (index > maxFreeParametersCount) // break; var nodeBuilder = new NodeBuilder(_document.Root[shape]); if (nodeBuilder.FunctionName == FunctionNames.Point) { nodeBuilder[1].TransformedPoint3D = GeomUtils.Point2DTo3D(sketchAx2, Parameters[ShapeToParamIndex[shape]], Parameters[ ShapeToParamIndex[shape] + 1]); index += 2; } if (nodeBuilder.FunctionName == FunctionNames.Circle) { nodeBuilder[0].RefTransformedPoint3D = GeomUtils.Point2DTo3D(sketchAx2, Parameters[ShapeToParamIndex[shape]], Parameters[ShapeToParamIndex[shape] + 1]); nodeBuilder[1].Real = Parameters[ShapeToParamIndex[shape] + 2]; index += 3; } } foreach (var shape in _document.Root.Children) { //if (index > maxFreeParametersCount) // break; var nodeBuilder = new NodeBuilder(shape.Value); if (nodeBuilder.FunctionName == FunctionNames.Arc) { if (ShapeToParamIndex.Keys.Contains(nodeBuilder.Dependency[0].Reference.Index)) { var centre = nodeBuilder.Dependency[0].RefTransformedPoint3D; var start = nodeBuilder.Dependency[1].RefTransformedPoint3D; var currentEnd = nodeBuilder.Dependency[2].RefTransformedPoint3D; var newEnd = GeomUtils.ProjectPointOnCircle(centre, start, currentEnd); if (newEnd != null) { var End = new Point3D(newEnd); nodeBuilder[2].RefTransformedPoint3D = new Point3D(End.X, End.Y, End.Z); } } error = 1; freeParametersCount = 0; while (error == 1 && freeParametersCount <= maxFreeParametersCount) { error = solver.SolveRef(ref Parameters, freeParametersCount, SetConstraintsList, 1); freeParametersCount += 2; } } } } foreach (var constr in softConstraints) { _document.Root.Remove(constr); } return(error); }