Add point-face distance constraints.
[git-p4: depot-paths = "//depot/solvespace/": change = 1778]
This commit is contained in:
parent
8a0809e6a0
commit
ccbda13a03
|
@ -11,6 +11,7 @@ char *Constraint::DescriptionString(void) {
|
||||||
case PT_PT_DISTANCE: s = "pt-pt-distance"; break;
|
case PT_PT_DISTANCE: s = "pt-pt-distance"; break;
|
||||||
case PT_LINE_DISTANCE: s = "pt-line-distance"; break;
|
case PT_LINE_DISTANCE: s = "pt-line-distance"; break;
|
||||||
case PT_PLANE_DISTANCE: s = "pt-plane-distance"; break;
|
case PT_PLANE_DISTANCE: s = "pt-plane-distance"; break;
|
||||||
|
case PT_FACE_DISTANCE: s = "pt-face-distance"; break;
|
||||||
case PT_IN_PLANE: s = "pt-in-plane"; break;
|
case PT_IN_PLANE: s = "pt-in-plane"; break;
|
||||||
case PT_ON_LINE: s = "pt-on-line"; break;
|
case PT_ON_LINE: s = "pt-on-line"; break;
|
||||||
case PT_ON_FACE: s = "pt-on-face"; break;
|
case PT_ON_FACE: s = "pt-on-face"; break;
|
||||||
|
@ -92,6 +93,10 @@ void Constraint::MenuConstrain(int id) {
|
||||||
c.type = PT_LINE_DISTANCE;
|
c.type = PT_LINE_DISTANCE;
|
||||||
c.ptA = gs.point[0];
|
c.ptA = gs.point[0];
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
|
} else if(gs.faces == 1 && gs.points == 1 && gs.n == 2) {
|
||||||
|
c.type = PT_FACE_DISTANCE;
|
||||||
|
c.ptA = gs.point[0];
|
||||||
|
c.entityA = gs.face[0];
|
||||||
} else if(gs.circlesOrArcs == 1 && gs.n == 1) {
|
} else if(gs.circlesOrArcs == 1 && gs.n == 1) {
|
||||||
c.type = DIAMETER;
|
c.type = DIAMETER;
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
|
@ -494,6 +499,15 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PT_FACE_DISTANCE: {
|
||||||
|
ExprVector pt = SS.GetEntity(ptA)->PointGetExprs();
|
||||||
|
Entity *f = SS.GetEntity(entityA);
|
||||||
|
ExprVector p0 = f->FaceGetPointExprs();
|
||||||
|
ExprVector n = f->FaceGetNormalExprs();
|
||||||
|
AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exprA), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EQUAL_LENGTH_LINES: {
|
case EQUAL_LENGTH_LINES: {
|
||||||
Entity *a = SS.GetEntity(entityA);
|
Entity *a = SS.GetEntity(entityA);
|
||||||
Entity *b = SS.GetEntity(entityB);
|
Entity *b = SS.GetEntity(entityB);
|
||||||
|
|
|
@ -4,6 +4,7 @@ bool Constraint::HasLabel(void) {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case PT_LINE_DISTANCE:
|
case PT_LINE_DISTANCE:
|
||||||
case PT_PLANE_DISTANCE:
|
case PT_PLANE_DISTANCE:
|
||||||
|
case PT_FACE_DISTANCE:
|
||||||
case PT_PT_DISTANCE:
|
case PT_PT_DISTANCE:
|
||||||
case DIAMETER:
|
case DIAMETER:
|
||||||
case LENGTH_RATIO:
|
case LENGTH_RATIO:
|
||||||
|
@ -112,11 +113,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PT_FACE_DISTANCE:
|
||||||
case PT_PLANE_DISTANCE: {
|
case PT_PLANE_DISTANCE: {
|
||||||
Vector pt = SS.GetEntity(ptA)->PointGetNum();
|
Vector pt = SS.GetEntity(ptA)->PointGetNum();
|
||||||
Entity *plane = SS.GetEntity(entityA);
|
Entity *enta = SS.GetEntity(entityA);
|
||||||
Vector n = plane->Normal()->NormalN();
|
Vector n, p;
|
||||||
Vector p = plane->WorkplaneGetOffset();
|
if(type == PT_PLANE_DISTANCE) {
|
||||||
|
n = enta->Normal()->NormalN();
|
||||||
|
p = enta->WorkplaneGetOffset();
|
||||||
|
} else {
|
||||||
|
n = enta->FaceGetNormalNum();
|
||||||
|
p = enta->FaceGetPointNum();
|
||||||
|
}
|
||||||
|
|
||||||
double d = (p.Minus(pt)).Dot(n);
|
double d = (p.Minus(pt)).Dot(n);
|
||||||
|
|
||||||
Vector closest = pt.Plus(n.WithMagnitude(d));
|
Vector closest = pt.Plus(n.WithMagnitude(d));
|
||||||
|
|
33
entity.cpp
33
entity.cpp
|
@ -570,13 +570,17 @@ bool Entity::IsFace(void) {
|
||||||
ExprVector Entity::FaceGetNormalExprs(void) {
|
ExprVector Entity::FaceGetNormalExprs(void) {
|
||||||
ExprVector r;
|
ExprVector r;
|
||||||
if(type == FACE_NORMAL_PT) {
|
if(type == FACE_NORMAL_PT) {
|
||||||
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
|
Vector v = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
|
||||||
|
r = ExprVector::From(v.WithMagnitude(1));
|
||||||
} else if(type == FACE_XPROD) {
|
} else if(type == FACE_XPROD) {
|
||||||
ExprVector vc = ExprVector::From(param[0], param[1], param[2]);
|
ExprVector vc = ExprVector::From(param[0], param[1], param[2]);
|
||||||
ExprVector vn = ExprVector::From(numVector);
|
ExprVector vn = ExprVector::From(numVector);
|
||||||
r = vc.Cross(vn);
|
r = vc.Cross(vn);
|
||||||
|
r = r.WithMagnitude(Expr::From(1.0));
|
||||||
} else if(type == FACE_N_ROT_TRANS) {
|
} else if(type == FACE_N_ROT_TRANS) {
|
||||||
// The numerical normal vector gets the rotation
|
// The numerical normal vector gets the rotation; the numerical
|
||||||
|
// normal has magnitude one, and the rotation doesn't change that,
|
||||||
|
// so there's no need to fix it up.
|
||||||
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
|
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
|
||||||
ExprQuaternion q =
|
ExprQuaternion q =
|
||||||
ExprQuaternion::From(param[3], param[4], param[5], param[6]);
|
ExprQuaternion::From(param[3], param[4], param[5], param[6]);
|
||||||
|
@ -598,7 +602,7 @@ Vector Entity::FaceGetNormalNum(void) {
|
||||||
Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]);
|
Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]);
|
||||||
r = q.Rotate(r);
|
r = q.Rotate(r);
|
||||||
} else oops();
|
} else oops();
|
||||||
return r;
|
return r.WithMagnitude(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprVector Entity::FaceGetPointExprs(void) {
|
ExprVector Entity::FaceGetPointExprs(void) {
|
||||||
|
@ -619,6 +623,22 @@ ExprVector Entity::FaceGetPointExprs(void) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector Entity::FaceGetPointNum(void) {
|
||||||
|
Vector r;
|
||||||
|
if(type == FACE_NORMAL_PT) {
|
||||||
|
r = SS.GetEntity(point[0])->PointGetNum();
|
||||||
|
} else if(type == FACE_XPROD) {
|
||||||
|
r = numPoint;
|
||||||
|
} else if(type == FACE_N_ROT_TRANS) {
|
||||||
|
// The numerical point gets the rotation and translation.
|
||||||
|
Vector trans = Vector::From(param[0], param[1], param[2]);
|
||||||
|
Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]);
|
||||||
|
r = q.Rotate(numPoint);
|
||||||
|
r = r.Plus(trans);
|
||||||
|
} else oops();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void Entity::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) {
|
void Entity::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) {
|
||||||
Equation eq;
|
Equation eq;
|
||||||
eq.e = expr;
|
eq.e = expr;
|
||||||
|
@ -656,10 +676,9 @@ void Entity::CalculateNumerical(void) {
|
||||||
actDistance = DistanceGetNum();
|
actDistance = DistanceGetNum();
|
||||||
}
|
}
|
||||||
if(IsFace()) {
|
if(IsFace()) {
|
||||||
ExprVector p = FaceGetPointExprs();
|
numPoint = FaceGetPointNum();
|
||||||
ExprVector n = FaceGetNormalExprs();
|
Vector n = FaceGetNormalNum();
|
||||||
numPoint = Vector::From( p.x->Eval(), p.y->Eval(), p.z->Eval());
|
numNormal = Quaternion::From(0, n.x, n.y, n.z);
|
||||||
numNormal = Quaternion::From(0, n.x->Eval(), n.y->Eval(), n.z->Eval());
|
|
||||||
}
|
}
|
||||||
visible = IsVisible();
|
visible = IsVisible();
|
||||||
}
|
}
|
||||||
|
|
5
expr.cpp
5
expr.cpp
|
@ -69,6 +69,11 @@ ExprVector ExprVector::ScaledBy(Expr *s) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExprVector ExprVector::WithMagnitude(Expr *s) {
|
||||||
|
Expr *m = Magnitude();
|
||||||
|
return ScaledBy(s->Div(m));
|
||||||
|
}
|
||||||
|
|
||||||
Expr *ExprVector::Magnitude(void) {
|
Expr *ExprVector::Magnitude(void) {
|
||||||
Expr *r;
|
Expr *r;
|
||||||
r = x->Square();
|
r = x->Square();
|
||||||
|
|
1
expr.h
1
expr.h
|
@ -134,6 +134,7 @@ public:
|
||||||
Expr *Dot(ExprVector b);
|
Expr *Dot(ExprVector b);
|
||||||
ExprVector Cross(ExprVector b);
|
ExprVector Cross(ExprVector b);
|
||||||
ExprVector ScaledBy(Expr *s);
|
ExprVector ScaledBy(Expr *s);
|
||||||
|
ExprVector WithMagnitude(Expr *s);
|
||||||
Expr *Magnitude(void);
|
Expr *Magnitude(void);
|
||||||
|
|
||||||
Vector Eval(void);
|
Vector Eval(void);
|
||||||
|
|
12
sketch.h
12
sketch.h
|
@ -318,6 +318,7 @@ public:
|
||||||
ExprVector FaceGetNormalExprs(void);
|
ExprVector FaceGetNormalExprs(void);
|
||||||
Vector FaceGetNormalNum(void);
|
Vector FaceGetNormalNum(void);
|
||||||
ExprVector FaceGetPointExprs(void);
|
ExprVector FaceGetPointExprs(void);
|
||||||
|
Vector FaceGetPointNum(void);
|
||||||
|
|
||||||
bool IsPoint(void);
|
bool IsPoint(void);
|
||||||
// Applies for any of the point types
|
// Applies for any of the point types
|
||||||
|
@ -399,11 +400,12 @@ public:
|
||||||
static const int USER_EQUATION = 10;
|
static const int USER_EQUATION = 10;
|
||||||
static const int POINTS_COINCIDENT = 20;
|
static const int POINTS_COINCIDENT = 20;
|
||||||
static const int PT_PT_DISTANCE = 30;
|
static const int PT_PT_DISTANCE = 30;
|
||||||
static const int PT_LINE_DISTANCE = 31;
|
static const int PT_PLANE_DISTANCE = 31;
|
||||||
static const int PT_PLANE_DISTANCE = 32;
|
static const int PT_LINE_DISTANCE = 32;
|
||||||
static const int PT_IN_PLANE = 40;
|
static const int PT_FACE_DISTANCE = 33;
|
||||||
static const int PT_ON_LINE = 41;
|
static const int PT_IN_PLANE = 41;
|
||||||
static const int PT_ON_FACE = 42;
|
static const int PT_ON_LINE = 42;
|
||||||
|
static const int PT_ON_FACE = 43;
|
||||||
static const int EQUAL_LENGTH_LINES = 50;
|
static const int EQUAL_LENGTH_LINES = 50;
|
||||||
static const int LENGTH_RATIO = 51;
|
static const int LENGTH_RATIO = 51;
|
||||||
static const int SYMMETRIC = 60;
|
static const int SYMMETRIC = 60;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user