Add projected point-point distance constraint.

[git-p4: depot-paths = "//depot/solvespace/": change = 2115]
solver
Jonathan Westhues 2010-01-27 10:15:06 -08:00
parent 46cabb4d73
commit 52f9be0925
9 changed files with 69 additions and 14 deletions

View File

@ -10,6 +10,7 @@ char *Constraint::DescriptionString(void) {
case PT_LINE_DISTANCE: s = "pt-line-distance"; break;
case PT_PLANE_DISTANCE: s = "pt-plane-distance"; break;
case PT_FACE_DISTANCE: s = "pt-face-distance"; break;
case PROJ_PT_DISTANCE: s = "proj-pt-pt-distance"; break;
case PT_IN_PLANE: s = "pt-in-plane"; break;
case PT_ON_LINE: s = "pt-on-line"; break;
case PT_ON_FACE: s = "pt-on-face"; break;
@ -122,6 +123,11 @@ void Constraint::MenuConstrain(int id) {
Entity *e = SK.GetEntity(gs.entity[0]);
c.ptA = e->point[0];
c.ptB = e->point[1];
} else if(gs.vectors == 1 && gs.points == 2 && gs.n == 3) {
c.type = PROJ_PT_DISTANCE;
c.ptA = gs.point[0];
c.ptB = gs.point[1];
c.entityA = gs.vector[0];
} else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) {
c.type = PT_PLANE_DISTANCE;
c.ptA = gs.point[0];
@ -138,17 +144,19 @@ void Constraint::MenuConstrain(int id) {
c.type = DIAMETER;
c.entityA = gs.entity[0];
} else {
Error("Bad selection for distance / diameter constraint. This "
"constraint can apply to:\n\n"
" * two points (distance between points)\n"
" * a line segment (length)\n"
" * a workplane and a point (minimum distance)\n"
" * a line segment and a point (minimum distance)\n"
" * a plane face and a point (minimum distance)\n"
" * a circle or an arc (diameter)\n");
Error(
"Bad selection for distance / diameter constraint. This "
"constraint can apply to:\n\n"
" * two points (distance between points)\n"
" * a line segment (length)\n"
" * two points and a line segment or normal (projected distance)\n"
" * a workplane and a point (minimum distance)\n"
" * a line segment and a point (minimum distance)\n"
" * a plane face and a point (minimum distance)\n"
" * a circle or an arc (diameter)\n");
return;
}
if(c.type == PT_PT_DISTANCE) {
if(c.type == PT_PT_DISTANCE || c.type == PROJ_PT_DISTANCE) {
Vector n = SS.GW.projRight.Cross(SS.GW.projUp);
Vector a = SK.GetEntity(c.ptA)->PointGetNum();
Vector b = SK.GetEntity(c.ptB)->PointGetNum();

View File

@ -189,6 +189,18 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) {
AddEq(l, Distance(workplane, ptA, ptB)->Minus(exA), 0);
break;
case PROJ_PT_DISTANCE: {
ExprVector pA = SK.GetEntity(ptA)->PointGetExprs(),
pB = SK.GetEntity(ptB)->PointGetExprs(),
dp = pB.Minus(pA);
ExprVector pp = SK.GetEntity(entityA)->VectorGetExprs();
pp = pp.WithMagnitude(Expr::From(1.0));
AddEq(l, (dp.Dot(pp))->Minus(exA), 0);
break;
}
case PT_LINE_DISTANCE:
AddEq(l,
PointLineDistance(workplane, ptA, entityA)->Minus(exA), 0);

View File

@ -6,6 +6,7 @@ bool Constraint::HasLabel(void) {
case PT_PLANE_DISTANCE:
case PT_FACE_DISTANCE:
case PT_PT_DISTANCE:
case PROJ_PT_DISTANCE:
case DIAMETER:
case LENGTH_RATIO:
case ANGLE:
@ -137,12 +138,16 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
}
}
void Constraint::DoProjectedPoint(Vector *r) {
Vector p = r->ProjectInto(workplane);
void Constraint::StippledLine(Vector a, Vector b) {
glLineStipple(4, 0x5555);
glEnable(GL_LINE_STIPPLE);
LineDrawOrGetDistance(p, *r);
LineDrawOrGetDistance(a, b);
glDisable(GL_LINE_STIPPLE);
}
void Constraint::DoProjectedPoint(Vector *r) {
Vector p = r->ProjectInto(workplane);
StippledLine(p, *r);
*r = p;
}
@ -421,6 +426,25 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
break;
}
case PROJ_PT_DISTANCE: {
Vector ap = SK.GetEntity(ptA)->PointGetNum(),
bp = SK.GetEntity(ptB)->PointGetNum(),
dp = (bp.Minus(ap)),
pp = SK.GetEntity(entityA)->VectorGetNum();
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
pp = pp.WithMagnitude(1);
double d = dp.Dot(pp);
Vector bpp = ap.Plus(pp.ScaledBy(d));
StippledLine(ap, bpp);
StippledLine(bp, bpp);
DoLineWithArrows(ref, ap, bpp, false);
DoLabel(ref, labelPos, gr, gu);
break;
}
case PT_FACE_DISTANCE:
case PT_PLANE_DISTANCE: {
Vector pt = SK.GetEntity(ptA)->PointGetNum();

View File

@ -264,7 +264,13 @@ the wrkpl member are marked with no star.
SLVS_C_PT_PT_DISTANCE*
The distance between points ptA and ptB is equal to valA.
The distance between points ptA and ptB is equal to valA. This is an
unsigned distance, so valA must always be positive.
SLVS_C_PROJ_PT_DISTANCE
The distance between points ptA and ptB, as projected along the line
or normal entityA, is equal to valA. This is a signed distance.
SLVS_C_POINTS_COINCIDENT*

View File

@ -164,6 +164,7 @@ case SLVS_C_PERPENDICULAR: t = Constraint::PERPENDICULAR; break;
case SLVS_C_ARC_LINE_TANGENT: t = Constraint::ARC_LINE_TANGENT; break;
case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break;
case SLVS_C_EQUAL_RADIUS: t = Constraint::EQUAL_RADIUS; break;
case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::PROJ_PT_DISTANCE; break;
default: dbp("bad constraint type %d", sc->type); return;
}

View File

@ -98,6 +98,7 @@ typedef struct {
#define SLVS_C_ARC_LINE_TANGENT 100027
#define SLVS_C_CUBIC_LINE_TANGENT 100028
#define SLVS_C_EQUAL_RADIUS 100029
#define SLVS_C_PROJ_PT_DISTANCE 100030
typedef struct {
Slvs_hConstraint h;

View File

@ -1154,6 +1154,7 @@ void GraphicsWindow::EditControlDone(char *s) {
SS.UndoRemember();
switch(c->type) {
case Constraint::PROJ_PT_DISTANCE:
case Constraint::PT_LINE_DISTANCE:
case Constraint::PT_FACE_DISTANCE:
case Constraint::PT_PLANE_DISTANCE: {

View File

@ -518,6 +518,7 @@ public:
static const int PT_PLANE_DISTANCE = 31;
static const int PT_LINE_DISTANCE = 32;
static const int PT_FACE_DISTANCE = 33;
static const int PROJ_PT_DISTANCE = 34;
static const int PT_IN_PLANE = 41;
static const int PT_ON_LINE = 42;
static const int PT_ON_FACE = 43;
@ -609,6 +610,7 @@ public:
void DoLineWithArrows(Vector ref, Vector a, Vector b, bool onlyOneExt);
int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b);
void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu);
void StippledLine(Vector a, Vector b);
void DoProjectedPoint(Vector *p);
void DoEqualLenTicks(Vector a, Vector b, Vector gn);
void DoEqualRadiusTicks(hEntity he);

View File

@ -1,6 +1,6 @@
replace show/hide links with icons?
lock point where dragged constraint
projected and signed distance constraints
remove toolbar icons for sketch in 3d, add View -> Align to Workplane
rounding, as a special group
associative entities from solid model, as a special group