USER FORUM

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

**Angles greater that 179 degree**

*(by Artem Zhidkov)*

Hello,

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,

Artem

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,

Artem

**(no subject)**

*(by Jonathan Westhues)*

http://solvespace.com/forum.pl?action=viewthread&parent=656

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.

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.

**(no subject)**

*(by NotSolveSpace)*

Best to use atan2 expression for angle constraints in plane

**(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.

**(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);

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);

**(no subject)**

*(by NotSolveSpace)*

also perfect to use abs sometimes

case ABS: return (a->Sgn())->Times(a->PartialWrt(p));

case ABS: return (a->Sgn())->Times(a->PartialWrt(p));

**(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

https://github.com/jwesthues/s...03fb4f7fb712d8bc0bb63ba6087f83

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

https://github.com/jwesthues/s...03fb4f7fb712d8bc0bb63ba6087f83

**(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.

**(no subject)**

*(by NotSolveSpace)*

Can you build something like this now?

http://makeagif.com/i/lYG7QN

http://makeagif.com/i/lYG7QN

**(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?

**(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

class UBERSOLVER_API Exp {

public:

Expr *expr;

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

class UBERSOLVER_API Exp {

public:

Expr *expr;

**Post a reply to this comment:**