Add symmetric about line constraint. This applies only when locked

in a workplane, since it would otherwise be ambiguous.

[git-p4: depot-paths = "//depot/solvespace/": change = 1817]
solver
Jonathan Westhues 2008-07-01 22:59:49 -08:00
parent 8a70efed05
commit 48c5018613
5 changed files with 79 additions and 5 deletions

View File

@ -22,6 +22,7 @@ char *Constraint::DescriptionString(void) {
case SYMMETRIC: s = "symmetric"; break;
case SYMMETRIC_HORIZ: s = "symmetric-h"; break;
case SYMMETRIC_VERT: s = "symmetric-v"; break;
case SYMMETRIC_LINE: s = "symmetric-line"; break;
case AT_MIDPOINT: s = "at-midpoint"; break;
case HORIZONTAL: s = "horizontal"; break;
case VERTICAL: s = "vertical"; break;
@ -70,7 +71,7 @@ void Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
void Constraint::MenuConstrain(int id) {
Constraint c;
memset(&c, 0, sizeof(c));
ZERO(&c);
c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane();
@ -235,11 +236,37 @@ void Constraint::MenuConstrain(int id) {
c.entityA = gs.entity[1-i];
c.ptA = line->point[0];
c.ptB = line->point[1];
} else if(SS.GW.LockedInWorkplane()
&& gs.lineSegments == 2 && gs.n == 2)
{
Entity *l0 = SS.GetEntity(gs.entity[0]),
*l1 = SS.GetEntity(gs.entity[1]);
if((l1->group.v != SS.GW.activeGroup.v) ||
(l1->construction && !(l0->construction)))
{
SWAP(Entity *, l0, l1);
}
c.ptA = l1->point[0];
c.ptB = l1->point[1];
c.entityA = l0->h;
c.type = SYMMETRIC_LINE;
} else if(SS.GW.LockedInWorkplane()
&& gs.lineSegments == 1 && gs.points == 2 && gs.n == 3)
{
c.ptA = gs.point[0];
c.ptB = gs.point[1];
c.entityA = gs.entity[0];
c.type = SYMMETRIC_LINE;
} else {
Error("Bad selection for symmetric constraint.");
return;
}
if(c.entityA.v == Entity::NO_ENTITY.v) {
if(c.type != 0) {
// Already done, symmetry about a line segment in a workplane
} else if(c.entityA.v == Entity::NO_ENTITY.v) {
// Horizontal / vertical symmetry, implicit symmetry plane
// normal to the workplane
if(c.workplane.v == Entity::FREE_IN_3D.v) {
Error("Must be locked in to workplane when constraining "
"symmetric without an explicit symmetry plane.");
@ -832,6 +859,39 @@ void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
break;
}
case SYMMETRIC_LINE: {
Entity *pa = SS.GetEntity(ptA);
Entity *pb = SS.GetEntity(ptB);
Expr *pau, *pav, *pbu, *pbv;
pa->PointGetExprsInWorkplane(workplane, &pau, &pav);
pb->PointGetExprsInWorkplane(workplane, &pbu, &pbv);
Entity *ln = SS.GetEntity(entityA);
Entity *la = SS.GetEntity(ln->point[0]);
Entity *lb = SS.GetEntity(ln->point[1]);
Expr *lau, *lav, *lbu, *lbv;
la->PointGetExprsInWorkplane(workplane, &lau, &lav);
lb->PointGetExprsInWorkplane(workplane, &lbu, &lbv);
Expr *dpu = pbu->Minus(pau), *dpv = pbv->Minus(pav);
Expr *dlu = lbu->Minus(lau), *dlv = lbv->Minus(lav);
// The line through the points is perpendicular to the line
// of symmetry.
AddEq(l, (dlu->Times(dpu))->Plus(dlv->Times(dpv)), 0);
// And the signed distances of the points to the line are
// equal in magnitude and opposite in sign, so sum to zero
Expr *dista = (dlv->Times(lau->Minus(pau)))->Minus(
(dlu->Times(lav->Minus(pav))));
Expr *distb = (dlv->Times(lau->Minus(pbu)))->Minus(
(dlu->Times(lav->Minus(pbv))));
AddEq(l, dista->Plus(distb), 1);
break;
}
case HORIZONTAL:
case VERTICAL: {
hEntity ha, hb;

View File

@ -491,9 +491,21 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
n = SS.GetEntity(workplane)->Normal()->NormalU(); goto s;
case SYMMETRIC_VERT:
n = SS.GetEntity(workplane)->Normal()->NormalV(); goto s;
case SYMMETRIC_LINE: {
Entity *ln = SS.GetEntity(entityA);
Vector la = SS.GetEntity(ln->point[0])->PointGetNum(),
lb = SS.GetEntity(ln->point[1])->PointGetNum();
la = la.ProjectInto(workplane);
lb = lb.ProjectInto(workplane);
n = lb.Minus(la);
Vector nw = SS.GetEntity(workplane)->Normal()->NormalN();
n = n.RotatedAbout(nw, PI/2);
goto s;
}
s:
Vector a = SS.GetEntity(ptA)->PointGetNum();
Vector b = SS.GetEntity(ptB)->PointGetNum();
for(int i = 0; i < 2; i++) {
Vector tail = (i == 0) ? a : b;
Vector d = (i == 0) ? b : a;

View File

@ -447,6 +447,7 @@ public:
static const int SYMMETRIC = 60;
static const int SYMMETRIC_HORIZ = 61;
static const int SYMMETRIC_VERT = 62;
static const int SYMMETRIC_LINE = 63;
static const int AT_MIDPOINT = 70;
static const int HORIZONTAL = 80;
static const int VERTICAL = 81;

View File

@ -463,10 +463,11 @@ void TextWindow::ShowGroupInfo(void) {
if(c->group.v == shown->group.v) {
char *s = c->DescriptionString();
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E",
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E %s",
(a & 1) ? 'd' : 'a',
c->h.v, (&TextWindow::ScreenSelectConstraint),
(&TextWindow::ScreenHoverConstraint), s);
(&TextWindow::ScreenHoverConstraint), s,
c->reference ? "(ref)" : "");
a++;
}
}

View File

@ -8,7 +8,7 @@ auto-generate circles and faces when lathing
copy the section geometry to other end when sweeping
cylindrical faces
draw explicit edges
symmetric about line segment
perpendicular constraint
long term