Add symmetry constraints without an explicit symmetry plane; these

use the horizontal or vertical axes of the active workplane. The
equations that we write from these are very fast (of the form u + v
= 0, or u - v = 0).

[git-p4: depot-paths = "//depot/solvespace/": change = 1720]
solver
Jonathan Westhues 2008-05-13 02:38:21 -08:00
parent 6031c99bec
commit aa5c621d82
3 changed files with 58 additions and 6 deletions

View File

@ -154,13 +154,17 @@ void Constraint::MenuConstrain(int id) {
break;
case GraphicsWindow::MNU_SYMMETRIC:
if(gs.points == 2 && gs.workplanes == 1 && gs.n == 3) {
c.type = SYMMETRIC;
if(gs.points == 2 &&
((gs.workplanes == 1 && gs.n == 3) ||
(gs.n == 2)))
{
c.entityA = gs.entity[0];
c.ptA = gs.point[0];
c.ptB = gs.point[1];
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = SYMMETRIC;
} else if(gs.lineSegments == 1 &&
((gs.workplanes == 1 && gs.n == 2) ||
(gs.n == 1)))
{
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
Entity *line = SS.GetEntity(gs.entity[i]);
c.entityA = gs.entity[1-i];
@ -170,6 +174,26 @@ void Constraint::MenuConstrain(int id) {
Error("Bad selection for symmetric constraint.");
return;
}
if(c.entityA.v == Entity::NO_ENTITY.v) {
if(c.workplane.v == Entity::FREE_IN_3D.v) {
Error("Must be locked in to workplane when constraining "
"symmetric without an explicit symmetry plane.");
return;
}
Vector pa = SS.GetEntity(c.ptA)->PointGetNum();
Vector pb = SS.GetEntity(c.ptB)->PointGetNum();
Vector dp = pa.Minus(pb);
Entity *norm = SS.GetEntity(c.workplane)->Normal();;
Vector u = norm->NormalU(), v = norm->NormalV();
if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) {
c.type = SYMMETRIC_HORIZ;
} else {
c.type = SYMMETRIC_VERT;
}
} else {
// Symmetry with a symmetry plane specified explicitly.
c.type = SYMMETRIC;
}
AddConstraint(&c);
break;
@ -567,6 +591,25 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
}
break;
case SYMMETRIC_HORIZ:
case SYMMETRIC_VERT: {
Entity *a = SS.GetEntity(ptA);
Entity *b = SS.GetEntity(ptB);
Expr *au, *av, *bu, *bv;
a->PointGetExprsInWorkplane(workplane, &au, &av);
b->PointGetExprsInWorkplane(workplane, &bu, &bv);
if(type == SYMMETRIC_HORIZ) {
AddEq(l, av->Minus(bv), 0);
AddEq(l, au->Plus(bu), 0);
} else {
AddEq(l, au->Minus(bu), 0);
AddEq(l, av->Plus(bv), 0);
}
break;
}
case HORIZONTAL:
case VERTICAL: {
hEntity ha, hb;

View File

@ -307,10 +307,17 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
break;
}
case SYMMETRIC: {
{
Vector n;
case SYMMETRIC:
n = SS.GetEntity(entityA)->Normal()->NormalN(); goto s;
case SYMMETRIC_HORIZ:
n = SS.GetEntity(workplane)->Normal()->NormalU(); goto s;
case SYMMETRIC_VERT:
n = SS.GetEntity(workplane)->Normal()->NormalV(); goto s;
s:
Vector a = SS.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum();
Vector n = SS.GetEntity(entityA)->Normal()->NormalN();
for(int i = 0; i < 2; i++) {
Vector tail = (i == 0) ? a : b;
Vector d = (i == 0) ? b : a;

View File

@ -331,6 +331,8 @@ public:
static const int EQUAL_LENGTH_LINES = 50;
static const int LENGTH_RATIO = 51;
static const int SYMMETRIC = 60;
static const int SYMMETRIC_HORIZ = 61;
static const int SYMMETRIC_VERT = 62;
static const int AT_MIDPOINT = 70;
static const int HORIZONTAL = 80;
static const int VERTICAL = 81;