SOLVESPACE -- parametric 2d/3d CAD

(you are viewing a thread; or go back to list of threads)

Angles greater that 179 degree (by Artem Zhidkov)

I have tried to play with angle between two lines, which have coincident point. When I try to set angle in range [179, 180] or [0, 1], sometimes the solver says about inconsistent system. Sometimes, it solves fine, but trying to move any line leads to inconsistent system again.

Is any way to fix this problem?

Thanks in advance,
Sat May 23 2015, 17:01:06
(no subject) (by Jonathan Westhues)

Basically, if you can express the constraint as an angle closer to 90 degrees (using a construction line for your datum if necessary), then convergence will be better.
Sat May 23 2015, 19:02:34
(no subject) (by NotSolveSpace)
Best to use atan2 expression for angle constraints in plane
Fri May 29 2015, 02:06:22
(no subject) (by Jonathan Westhues)
It's not straightforward to define the range and derivative of atan2() for good convergence. I'd expect that the easiest way to improve performance there would be analogous to what's already done for arc-length-equals-line-length.
Fri May 29 2015, 03:17:16
(no subject) (by NotSolveSpace)
Ive done it through atan2 & decided to use this expression inside parallel & perpendicular. its best, trust me.

Expr *Expr::PartialWrt(Param *p) {
case ATAN2:
da = a->Div(b->Square()->Plus(a->Square()))->Negate()->Times(b->PartialWrt(p));
db = b->Div(b->Square()->Plus(a->Square()))->Times(a->PartialWrt(p));
return da->Plus(db);
Mon Jun 8 2015, 04:27:48
(no subject) (by NotSolveSpace)
also perfect to use abs sometimes

case ABS: return (a->Sgn())->Times(a->PartialWrt(p));
Mon Jun 8 2015, 04:32:14
(no subject) (by Jonathan Westhues)
I'm not sure what those snippets of code are intended to convey. It's trivial to define atan2(); the nuisance is unwrapping the phase, which that doesn't address. And abs() has constant derivatives, so it provides no information to the solver; so you'll never get from positive to negative input except by accident.

In any case, upon investigation, the solution still converges fine at small (~0.1 degree) angles, despite the dilution of precision from subtracting two dot products nearly equal to one; doubles are nice that way. The only problem is that we falsely detected an inconsistent system, due to an inappropriate tolerance in the rank test. So performance should be improved with just
Mon Jun 8 2015, 14:34:27
(no subject) (by NotSolveSpace)
Man, you dont listen to me. I dont suppose about atan2 and abs, i have it working, working good. Even parallel/perpendicular must be atan2 to work perfect. It is better convergence than dot product. Only thing should be perfomed is using expressions on plane when there are both points and constraint is in the same plane.
Wed Jun 10 2015, 09:55:59
(no subject) (by NotSolveSpace)
Can you build something like this now?
Thu Jun 11 2015, 01:02:06
(no subject) (by Jonathan Westhues)
Perhaps you've built something good, with an approach different from what I took. You've never posted source code for anyone to evaluate or use, though. Why not share it?
Thu Jun 11 2015, 02:33:05
(no subject) (by NotSolveSpace)
no, there is no different approach. it is yours solver just refactored little bit with different equations. there are only few basic equations

Exp expressionAngle2d(const ExprVector &d0, const ExprVector &d1) {
Exp nu = d1.x * d0.x + d1.y * d0.y;
Exp nv = d0.x * d1.y - d0.y * d1.x;
return atan2(nv, nu);

Exp expressionAngle3d(const ExprVector &d0, const ExprVector &d1) {
return acos(dot(d0, d1) / (length(d0) * length(d1)));

Exp expressionDistancePointLine2d(const ExprVector &p, const ExprVector &p0, const ExprVector &p1) {
return ((p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y + p0.x * p1.y - p1.x * p0.y) / sqrt(sqr(p1.x - p0.x) + sqr(p1.y - p0.y));

Exp expressionDistancePointLine2dSqr(const ExprVector &p, const ExprVector &p0, const ExprVector &p1) {
return sqr((p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y + p0.x * p1.y - p1.x * p0.y) / (sqr(p1.x - p0.x) + sqr(p1.y - p0.y));

Exp expressionDistancePointLine3d(const ExprVector &p, const ExprVector &p0, const ExprVector &p1) {
ExprVector d = p0 - p1;
return length(cross(d, p0 - p)) / length(d);

Exp expressionDistancePointLine3dSqr(const ExprVector &p, const ExprVector &p0, const ExprVector &p1) {
ExprVector d = p0 - p1;
return lengthSqr(cross(d, p0 - p)) / lengthSqr(d);

Exp expressionPointsDistance2d(const ExprVector &p0, const ExprVector &p1) {
return sqrt(sqr(p1.x - p0.x) + sqr(p1.y - p0.y));

Exp expressionPointsDistance2dSqr(const ExprVector &p0, const ExprVector &p1) {
return sqr(p1.x - p0.x) + sqr(p1.y - p0.y);

Exp expressionPointsDistance3d(const ExprVector &p0, const ExprVector &p1) {
return sqrt(sqr(p1.x - p0.x) + sqr(p1.y - p0.y) + sqr(p1.z - p0.z));

Exp expressionPointsDistance3dSqr(const ExprVector &p0, const ExprVector &p1) {
return sqr(p1.x - p0.x) + sqr(p1.y - p0.y) + sqr(p1.z - p0.z);

all the relations based on it.
Exp is just Expr * with overloaded operators


Expr *expr;
Mon Jun 22 2015, 06:02:25
Post a reply to this comment:
Your Name:
Your Email:
(no HTML tags; use plain text, and hit Enter for a line break)
Attached file (if you want, 5 MB max):
© 2008-2018 SolveSpace contributors. Most recent update Nov 22 2018.