Add a perpendicular constraint; identical to constraining a ninety

degree angle, but shows with a right angle symbol instead of a
numerical angle you can edit.

[git-p4: depot-paths = "//depot/solvespace/": change = 1819]
This commit is contained in:
Jonathan Westhues 2008-07-02 01:21:29 -08:00
parent 1bc68779d9
commit fd4abd5519
6 changed files with 64 additions and 3 deletions

View File

@ -31,6 +31,7 @@ char *Constraint::DescriptionString(void) {
case SAME_ORIENTATION: s = "same-orientation"; break; case SAME_ORIENTATION: s = "same-orientation"; break;
case ANGLE: s = "angle"; break; case ANGLE: s = "angle"; break;
case PARALLEL: s = "parallel"; break; case PARALLEL: s = "parallel"; break;
case PERPENDICULAR: s = "perpendicular"; break;
case EQUAL_RADIUS: s = "eq-radius"; break; case EQUAL_RADIUS: s = "eq-radius"; break;
case COMMENT: s = "comment"; break; case COMMENT: s = "comment"; break;
default: s = "???"; break; default: s = "???"; break;
@ -425,6 +426,18 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_PERPENDICULAR:
if(gs.vectors == 2 && gs.n == 2) {
c.type = PERPENDICULAR;
c.entityA = gs.vector[0];
c.entityB = gs.vector[1];
} else {
Error("Bad selection for perpendicular constraint.");
return;
}
AddConstraint(&c);
break;
case GraphicsWindow::MNU_COMMENT: case GraphicsWindow::MNU_COMMENT:
c.type = COMMENT; c.type = COMMENT;
c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT"); c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
@ -942,6 +955,7 @@ void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
break; break;
} }
case PERPENDICULAR:
case ANGLE: { case ANGLE: {
Entity *a = SS.GetEntity(entityA); Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB); Entity *b = SS.GetEntity(entityB);
@ -965,8 +979,16 @@ void Constraint::GenerateReal(IdList<Equation,hEquation> *l) {
Expr *dot = (ua->Times(ub))->Plus(va->Times(vb)); Expr *dot = (ua->Times(ub))->Plus(va->Times(vb));
c = dot->Div(maga->Times(magb)); c = dot->Div(maga->Times(magb));
} }
Expr *rads = exA->Times(Expr::From(PI/180)); if(type == ANGLE) {
AddEq(l, c->Minus(rads->Cos()), 0); // The direction cosine is equal to the cosine of the
// specified angle
Expr *rads = exA->Times(Expr::From(PI/180));
AddEq(l, c->Minus(rads->Cos()), 0);
} else {
// The dot product (and therefore the direction cosine)
// is equal to zero, perpendicular.
AddEq(l, c, 0);
}
break; break;
} }

View File

@ -373,6 +373,43 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
break; break;
} }
case PERPENDICULAR: {
Vector u, v;
Vector rn, ru;
if(workplane.v == Entity::FREE_IN_3D.v) {
rn = gn;
ru = gu;
} else {
Entity *normal = SS.GetEntity(workplane)->Normal();
rn = normal->NormalN();
ru = normal->NormalV(); // ru meaning r_up, not u/v
}
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
if(i == 0) {
// Calculate orientation of perpendicular sign only
// once, so that it's the same both times it's drawn
u = e->VectorGetNum();
u = u.WithMagnitude(16/SS.GW.scale);
v = (rn.Cross(u)).WithMagnitude(16/SS.GW.scale);
if(fabs(u.Dot(ru)) < fabs(v.Dot(ru))) {
SWAP(Vector, u, v);
}
if(u.Dot(ru) < 0) u = u.ScaledBy(-1);
}
Vector p = e->VectorGetRefPoint();
Vector s = p.Plus(u).Plus(v);
LineDrawOrGetDistance(s, s.Plus(v));
Vector m = s.Plus(v.ScaledBy(0.5));
LineDrawOrGetDistance(m, m.Plus(u));
}
break;
}
case PARALLEL: { case PARALLEL: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB); Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);

View File

@ -86,6 +86,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 1, "At &Midpoint\tShift+M", MNU_AT_MIDPOINT, 'M'|S, mCon }, { 1, "At &Midpoint\tShift+M", MNU_AT_MIDPOINT, 'M'|S, mCon },
{ 1, "S&ymmetric\tShift+Y", MNU_SYMMETRIC, 'Y'|S, mCon }, { 1, "S&ymmetric\tShift+Y", MNU_SYMMETRIC, 'Y'|S, mCon },
{ 1, "Para&llel\tShift+L", MNU_PARALLEL, 'L'|S, mCon }, { 1, "Para&llel\tShift+L", MNU_PARALLEL, 'L'|S, mCon },
{ 1, "&Perpendicular\tShift+P", MNU_PERPENDICULAR, 'P'|S, mCon },
{ 1, "Same Orient&ation\tShift+A", MNU_ORIENTED_SAME, 'A'|S, mCon }, { 1, "Same Orient&ation\tShift+A", MNU_ORIENTED_SAME, 'A'|S, mCon },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
{ 1, "Comment\tShift+C", MNU_COMMENT, 'C'|S, mCon }, { 1, "Comment\tShift+C", MNU_COMMENT, 'C'|S, mCon },

View File

@ -456,6 +456,7 @@ public:
static const int SAME_ORIENTATION = 110; static const int SAME_ORIENTATION = 110;
static const int ANGLE = 120; static const int ANGLE = 120;
static const int PARALLEL = 121; static const int PARALLEL = 121;
static const int PERPENDICULAR = 122;
static const int EQUAL_RADIUS = 130; static const int EQUAL_RADIUS = 130;
static const int COMMENT = 1000; static const int COMMENT = 1000;

1
ui.h
View File

@ -196,6 +196,7 @@ public:
MNU_HORIZONTAL, MNU_HORIZONTAL,
MNU_VERTICAL, MNU_VERTICAL,
MNU_PARALLEL, MNU_PARALLEL,
MNU_PERPENDICULAR,
MNU_ORIENTED_SAME, MNU_ORIENTED_SAME,
MNU_COMMENT, MNU_COMMENT,
} MenuId; } MenuId;

View File

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