Add a new length-difference constraint.

This constraint requires the lengths of two line segments to
differ by a constant.
It can be useful to define the tolerances when making joints.
pull/4/head
ruevs 2015-10-27 12:28:33 +02:00 committed by whitequark
parent 8c2e94a01a
commit b23336b589
12 changed files with 47 additions and 3 deletions

View File

@ -313,6 +313,10 @@ SLVS_C_LENGTH_RATIO*
The length of line entityA divided by the length of line entityB is
equal to valA.
SLVS_C_LENGTH_DIFFERENCE*
The lengths of line entityA and line entityB differ by valA.
SLVS_C_EQ_LEN_PT_LINE_D*
The length of the line entityA is equal to the distance from point

View File

@ -511,6 +511,7 @@ Module VbDemo
Public Const SLVS_C_PROJ_PT_DISTANCE As Integer = 100030
Public Const SLVS_C_WHERE_DRAGGED As Integer = 100031
Public Const SLVS_C_CURVE_CURVE_TANGENT As Integer = 100032
Public Const SLVS_C_LENGTH_DIFFERENCE As Integer = 100033
<StructLayout(LayoutKind.Sequential)> Public Structure Slvs_Constraint
Public h As UInteger

View File

@ -112,6 +112,7 @@ typedef struct {
#define SLVS_C_PROJ_PT_DISTANCE 100030
#define SLVS_C_WHERE_DRAGGED 100031
#define SLVS_C_CURVE_CURVE_TANGENT 100032
#define SLVS_C_LENGTH_DIFFERENCE 100033
typedef struct {
Slvs_hConstraint h;

View File

@ -24,6 +24,7 @@ char *Constraint::DescriptionString(void) {
case EQ_LEN_PT_LINE_D: s = "eq-length-and-pt-ln-dist"; break;
case EQ_PT_LN_DISTANCES: s = "eq-pt-line-distances"; break;
case LENGTH_RATIO: s = "length-ratio"; break;
case LENGTH_DIFFERENCE: s = "length-difference"; break;
case SYMMETRIC: s = "symmetric"; break;
case SYMMETRIC_HORIZ: s = "symmetric-h"; break;
case SYMMETRIC_VERT: s = "symmetric-v"; break;
@ -322,6 +323,23 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c);
break;
case GraphicsWindow::MNU_DIFFERENCE:
if(gs.lineSegments == 2 && gs.n == 2) {
c.type = LENGTH_DIFFERENCE;
c.entityA = gs.entity[0];
c.entityB = gs.entity[1];
} else {
Error("Bad selection for length difference constraint. This "
"constraint can apply to:\n\n"
" * two line segments\n");
return;
}
c.valA = 0;
c.ModifyToSatisfy();
AddConstraint(&c);
break;
case GraphicsWindow::MNU_AT_MIDPOINT:
if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) {
c.type = AT_MIDPOINT;

View File

@ -18,6 +18,7 @@ bool ConstraintBase::HasLabel(void) {
case PROJ_PT_DISTANCE:
case DIAMETER:
case LENGTH_RATIO:
case LENGTH_DIFFERENCE:
case ANGLE:
case COMMENT:
return true;
@ -279,6 +280,15 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
break;
}
case LENGTH_DIFFERENCE: {
EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB);
Expr *la = Distance(workplane, a->point[0], a->point[1]);
Expr *lb = Distance(workplane, b->point[0], b->point[1]);
AddEq(l, (la->Minus(lb))->Minus(exA), 0);
break;
}
case DIAMETER: {
EntityBase *circle = SK.GetEntity(entityA);
Expr *r = circle->CircleGetRadiusExpr();

View File

@ -63,6 +63,8 @@ char *Constraint::Label(void) {
sprintf(Ret, "%.2f", valA);
} else if(type == LENGTH_RATIO) {
sprintf(Ret, "%.3f:1", valA);
} else if(type == LENGTH_DIFFERENCE) {
sprintf(Ret, "%.3f", valA);
} else if(type == COMMENT) {
strcpy(Ret, comment.str);
} else if(type == DIAMETER) {
@ -853,6 +855,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
}
case LENGTH_RATIO:
case LENGTH_DIFFERENCE:
case EQUAL_LENGTH_LINES: {
Vector a, b = Vector::From(0, 0, 0);
for(int i = 0; i < 2; i++) {
@ -867,7 +870,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
DoEqualLenTicks(a, b, gn);
}
if(type == LENGTH_RATIO) {
if((type == LENGTH_RATIO) || (type == LENGTH_DIFFERENCE)) {
Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset);
DoLabel(ref, labelPos, gr, gu);
}

View File

@ -139,6 +139,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 1, "&On Point / Curve / Plane", MNU_ON_ENTITY, 'O', IN, mCon },
{ 1, "E&qual Length / Radius / Angle", MNU_EQUAL, 'Q', IN, mCon },
{ 1, "Length Ra&tio", MNU_RATIO, 'Z', IN, mCon },
{ 1, "Length Diff&erence", MNU_DIFFERENCE, 'J', IN, mCon },
{ 1, "At &Midpoint", MNU_AT_MIDPOINT, 'M', IN, mCon },
{ 1, "S&ymmetric", MNU_SYMMETRIC, 'Y', IN, mCon },
{ 1, "Para&llel / Tangent", MNU_PARALLEL, 'L', IN, mCon },

View File

@ -156,6 +156,7 @@ case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::EQ_LEN_PT_LINE_D; break;
case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE: t = Constraint::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::LENGTH_DIFFERENCE; break;
case SLVS_C_SYMMETRIC: t = Constraint::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT: t = Constraint::SYMMETRIC_VERT; break;

View File

@ -1155,6 +1155,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
case Constraint::ANGLE:
case Constraint::LENGTH_RATIO:
case Constraint::LENGTH_DIFFERENCE:
sprintf(s, "%.3f", c->valA);
break;
@ -1206,7 +1207,8 @@ void GraphicsWindow::EditControlDone(const char *s) {
case Constraint::PROJ_PT_DISTANCE:
case Constraint::PT_LINE_DISTANCE:
case Constraint::PT_FACE_DISTANCE:
case Constraint::PT_PLANE_DISTANCE: {
case Constraint::PT_PLANE_DISTANCE:
case Constraint::LENGTH_DIFFERENCE: {
// The sign is not displayed to the user, but this is a signed
// distance internally. To flip the sign, the user enters a
// negative distance.

View File

@ -555,6 +555,7 @@ public:
EQ_PT_LN_DISTANCES = 53,
EQUAL_ANGLE = 54,
EQUAL_LINE_ARC_LEN = 55,
LENGTH_DIFFERENCE = 56,
SYMMETRIC = 60,
SYMMETRIC_HORIZ = 61,
SYMMETRIC_VERT = 62,

View File

@ -560,7 +560,8 @@ void SolveSpaceUI::MenuAnalyze(int id) {
SS.TW.shown.dimSteps = 10;
SS.TW.shown.dimIsDistance =
(c->type != Constraint::ANGLE) &&
(c->type != Constraint::LENGTH_RATIO);
(c->type != Constraint::LENGTH_RATIO) &&
(c->type != Constraint::LENGTH_DIFFERENCE);
SS.TW.shown.constraint = c->h;
SS.TW.shown.screen = TextWindow::SCREEN_STEP_DIMENSION;

View File

@ -404,6 +404,7 @@ public:
MNU_REFERENCE,
MNU_EQUAL,
MNU_RATIO,
MNU_DIFFERENCE,
MNU_ON_ENTITY,
MNU_SYMMETRIC,
MNU_AT_MIDPOINT,