Add point-face distance constraints.
[git-p4: depot-paths = "//depot/solvespace/": change = 1778]solver
parent
8a0809e6a0
commit
ccbda13a03
|
@ -11,6 +11,7 @@ char *Constraint::DescriptionString(void) {
|
|||
case PT_PT_DISTANCE: s = "pt-pt-distance"; break;
|
||||
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 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;
|
||||
|
@ -92,6 +93,10 @@ void Constraint::MenuConstrain(int id) {
|
|||
c.type = PT_LINE_DISTANCE;
|
||||
c.ptA = gs.point[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) {
|
||||
c.type = DIAMETER;
|
||||
c.entityA = gs.entity[0];
|
||||
|
@ -494,6 +499,15 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
|||
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: {
|
||||
Entity *a = SS.GetEntity(entityA);
|
||||
Entity *b = SS.GetEntity(entityB);
|
||||
|
|
|
@ -4,6 +4,7 @@ bool Constraint::HasLabel(void) {
|
|||
switch(type) {
|
||||
case PT_LINE_DISTANCE:
|
||||
case PT_PLANE_DISTANCE:
|
||||
case PT_FACE_DISTANCE:
|
||||
case PT_PT_DISTANCE:
|
||||
case DIAMETER:
|
||||
case LENGTH_RATIO:
|
||||
|
@ -112,11 +113,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
break;
|
||||
}
|
||||
|
||||
case PT_FACE_DISTANCE:
|
||||
case PT_PLANE_DISTANCE: {
|
||||
Vector pt = SS.GetEntity(ptA)->PointGetNum();
|
||||
Entity *plane = SS.GetEntity(entityA);
|
||||
Vector n = plane->Normal()->NormalN();
|
||||
Vector p = plane->WorkplaneGetOffset();
|
||||
Entity *enta = SS.GetEntity(entityA);
|
||||
Vector n, p;
|
||||
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);
|
||||
|
||||
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 r;
|
||||
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) {
|
||||
ExprVector vc = ExprVector::From(param[0], param[1], param[2]);
|
||||
ExprVector vn = ExprVector::From(numVector);
|
||||
r = vc.Cross(vn);
|
||||
r = r.WithMagnitude(Expr::From(1.0));
|
||||
} 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);
|
||||
ExprQuaternion q =
|
||||
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]);
|
||||
r = q.Rotate(r);
|
||||
} else oops();
|
||||
return r;
|
||||
return r.WithMagnitude(1);
|
||||
}
|
||||
|
||||
ExprVector Entity::FaceGetPointExprs(void) {
|
||||
|
@ -619,6 +623,22 @@ ExprVector Entity::FaceGetPointExprs(void) {
|
|||
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) {
|
||||
Equation eq;
|
||||
eq.e = expr;
|
||||
|
@ -656,10 +676,9 @@ void Entity::CalculateNumerical(void) {
|
|||
actDistance = DistanceGetNum();
|
||||
}
|
||||
if(IsFace()) {
|
||||
ExprVector p = FaceGetPointExprs();
|
||||
ExprVector n = FaceGetNormalExprs();
|
||||
numPoint = Vector::From( p.x->Eval(), p.y->Eval(), p.z->Eval());
|
||||
numNormal = Quaternion::From(0, n.x->Eval(), n.y->Eval(), n.z->Eval());
|
||||
numPoint = FaceGetPointNum();
|
||||
Vector n = FaceGetNormalNum();
|
||||
numNormal = Quaternion::From(0, n.x, n.y, n.z);
|
||||
}
|
||||
visible = IsVisible();
|
||||
}
|
||||
|
|
5
expr.cpp
5
expr.cpp
|
@ -69,6 +69,11 @@ ExprVector ExprVector::ScaledBy(Expr *s) {
|
|||
return r;
|
||||
}
|
||||
|
||||
ExprVector ExprVector::WithMagnitude(Expr *s) {
|
||||
Expr *m = Magnitude();
|
||||
return ScaledBy(s->Div(m));
|
||||
}
|
||||
|
||||
Expr *ExprVector::Magnitude(void) {
|
||||
Expr *r;
|
||||
r = x->Square();
|
||||
|
|
1
expr.h
1
expr.h
|
@ -134,6 +134,7 @@ public:
|
|||
Expr *Dot(ExprVector b);
|
||||
ExprVector Cross(ExprVector b);
|
||||
ExprVector ScaledBy(Expr *s);
|
||||
ExprVector WithMagnitude(Expr *s);
|
||||
Expr *Magnitude(void);
|
||||
|
||||
Vector Eval(void);
|
||||
|
|
12
sketch.h
12
sketch.h
|
@ -318,6 +318,7 @@ public:
|
|||
ExprVector FaceGetNormalExprs(void);
|
||||
Vector FaceGetNormalNum(void);
|
||||
ExprVector FaceGetPointExprs(void);
|
||||
Vector FaceGetPointNum(void);
|
||||
|
||||
bool IsPoint(void);
|
||||
// Applies for any of the point types
|
||||
|
@ -399,11 +400,12 @@ public:
|
|||
static const int USER_EQUATION = 10;
|
||||
static const int POINTS_COINCIDENT = 20;
|
||||
static const int PT_PT_DISTANCE = 30;
|
||||
static const int PT_LINE_DISTANCE = 31;
|
||||
static const int PT_PLANE_DISTANCE = 32;
|
||||
static const int PT_IN_PLANE = 40;
|
||||
static const int PT_ON_LINE = 41;
|
||||
static const int PT_ON_FACE = 42;
|
||||
static const int PT_PLANE_DISTANCE = 31;
|
||||
static const int PT_LINE_DISTANCE = 32;
|
||||
static const int PT_FACE_DISTANCE = 33;
|
||||
static const int PT_IN_PLANE = 41;
|
||||
static const int PT_ON_LINE = 42;
|
||||
static const int PT_ON_FACE = 43;
|
||||
static const int EQUAL_LENGTH_LINES = 50;
|
||||
static const int LENGTH_RATIO = 51;
|
||||
static const int SYMMETRIC = 60;
|
||||
|
|
Loading…
Reference in New Issue