diff --git a/constraint.cpp b/constraint.cpp index f745983..57d8609 100644 --- a/constraint.cpp +++ b/constraint.cpp @@ -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 *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; diff --git a/drawconstraint.cpp b/drawconstraint.cpp index d519fd7..d0885f8 100644 --- a/drawconstraint.cpp +++ b/drawconstraint.cpp @@ -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(); } } diff --git a/dsc.h b/dsc.h index bee5702..86d5e3e 100644 --- a/dsc.h +++ b/dsc.h @@ -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 diff --git a/graphicswin.cpp b/graphicswin.cpp index cded333..fb12b7c 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -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 }, diff --git a/sketch.h b/sketch.h index c1483d0..981d64e 100644 --- a/sketch.h +++ b/sketch.h @@ -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; diff --git a/ui.h b/ui.h index d57b762..c3aaaea 100644 --- a/ui.h +++ b/ui.h @@ -96,6 +96,7 @@ public: MNU_LINE_SEGMENT, // Constrain MNU_DISTANCE_DIA, + MNU_EQUAL, MNU_ON_ENTITY, MNU_SOLVE_NOW, } MenuId; diff --git a/util.cpp b/util.cpp index b336a41..8cc4f61 100644 --- a/util.cpp +++ b/util.cpp @@ -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;