Add projected point-point distance constraint.
[git-p4: depot-paths = "//depot/solvespace/": change = 2115]solver
parent
46cabb4d73
commit
52f9be0925
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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*
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
2
sketch.h
2
sketch.h
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue