Add an equal length constraint for line segments.

[git-p4: depot-paths = "//depot/solvespace/": change = 1680]
This commit is contained in:
Jonathan Westhues 2008-04-21 21:00:49 -08:00
parent 9b1b255e85
commit 1f77024771
7 changed files with 55 additions and 3 deletions

View File

@ -49,6 +49,18 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c);
break;
case GraphicsWindow::MNU_EQUAL:
if(gs.lineSegments == 2 && gs.n == 2) {
c.type = EQUAL_LENGTH_LINES;
c.entityA = gs.entity[0];
c.entityB = gs.entity[1];
} else {
Error("Bad selection for equal length / radius constraint.");
return;
}
AddConstraint(&c);
break;
case GraphicsWindow::MNU_SOLVE_NOW:
SS.Solve();
return;
@ -104,6 +116,14 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
AddEq(l, Distance(ptA, ptB)->Minus(exprA), 0);
break;
case EQUAL_LENGTH_LINES: {
Entity *a = SS.GetEntity(entityA);
Entity *b = SS.GetEntity(entityB);
AddEq(l, Distance(a->assoc[0], a->assoc[1])->Minus(
Distance(b->assoc[0], b->assoc[1])), 0);
break;
}
case POINTS_COINCIDENT: {
Expr *ax, *ay, *az;
Expr *bx, *by, *bz;

View File

@ -98,6 +98,20 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
break;
}
case EQUAL_LENGTH_LINES: {
for(int i = 0; i < 2; i++) {
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
Vector a = SS.GetEntity(e->assoc[0])->PointGetCoords();
Vector b = SS.GetEntity(e->assoc[1])->PointGetCoords();
Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
Vector ab = a.Minus(b);
Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);
LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
}
break;
}
default: oops();
}
}

2
dsc.h
View File

@ -54,6 +54,8 @@ public:
Point2d ScaledBy(double s);
double DistanceTo(Point2d p);
double DistanceToLine(Point2d p0, Point2d dp, bool segment);
double Magnitude(void);
Point2d WithMagnitude(double v);
};
template <class T, class H>

View File

@ -70,7 +70,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 1, "&Vertical\tShift+V", 0, 'V'|S, NULL },
{ 1, NULL, 0, NULL },
{ 1, "&On Point / Curve / Plane\tShift+O", MNU_ON_ENTITY, 'O'|S, mCon },
{ 1, "E&qual Length / Radius\tShift+Q", 0, 'Q'|S, NULL },
{ 1, "E&qual Length / Radius\tShift+Q", MNU_EQUAL, 'Q'|S, mCon },
{ 1, "At &Midpoint\tShift+M", 0, 'M'|S, NULL },
{ 1, "S&ymmetric\tShift+Y", 0, 'Y'|S, NULL },
{ 1, NULL, 0, NULL },

View File

@ -213,9 +213,10 @@ public:
static const int PT_PT_DISTANCE = 30;
static const int PT_LINE_DISTANCE = 31;
static const int PT_IN_PLANE = 40;
static const int EQUAL_LENGTH_LINES = 50;
static const int HORIZONTAL = 40;
static const int VERTICAL = 41;
static const int HORIZONTAL = 80;
static const int VERTICAL = 81;
int tag;
hConstraint h;

1
ui.h
View File

@ -96,6 +96,7 @@ public:
MNU_LINE_SEGMENT,
// Constrain
MNU_DISTANCE_DIA,
MNU_EQUAL,
MNU_ON_ENTITY,
MNU_SOLVE_NOW,
} MenuId;

View File

@ -248,6 +248,20 @@ Point2d Point2d::ScaledBy(double s) {
return r;
}
double Point2d::Magnitude(void) {
return sqrt(x*x + y*y);
}
Point2d Point2d::WithMagnitude(double v) {
double m = Magnitude();
if(m < 0.001) {
Point2d r = { v, 0 };
return r;
} else {
return ScaledBy(v/Magnitude());
}
}
double Point2d::DistanceTo(Point2d p) {
double dx = x - p.x;
double dy = y - p.y;