Make at-midpoint constraint also work to constrain midpoint of a
line segment on a plane. And simplify that code a bit, and improve display. [git-p4: depot-paths = "//depot/solvespace/": change = 1702]solver
parent
b7e8b99f37
commit
658b7df50f
|
@ -96,6 +96,11 @@ void Constraint::MenuConstrain(int id) {
|
||||||
c.type = AT_MIDPOINT;
|
c.type = AT_MIDPOINT;
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
c.ptA = gs.point[0];
|
c.ptA = gs.point[0];
|
||||||
|
} else if(gs.lineSegments == 1 && gs.planes == 1 && gs.n == 2) {
|
||||||
|
c.type = AT_MIDPOINT;
|
||||||
|
int i = SS.GetEntity(gs.entity[0])->HasPlane() ? 1 : 0;
|
||||||
|
c.entityA = gs.entity[i];
|
||||||
|
c.entityB = gs.entity[1-i];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for at midpoint constraint.");
|
Error("Bad selection for at midpoint constraint.");
|
||||||
return;
|
return;
|
||||||
|
@ -265,6 +270,15 @@ Expr *Constraint::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExprVector Constraint::PointInThreeSpace(hEntity workplane, Expr *u, Expr *v) {
|
||||||
|
ExprVector ub, vb, ob;
|
||||||
|
Entity *w = SS.GetEntity(workplane);
|
||||||
|
w->WorkplaneGetBasisExprs(&ub, &vb);
|
||||||
|
ob = w->WorkplaneGetOffsetExprs();
|
||||||
|
|
||||||
|
return (ub.ScaledBy(u)).Plus(vb.ScaledBy(v)).Plus(ob);
|
||||||
|
}
|
||||||
|
|
||||||
void Constraint::ModifyToSatisfy(void) {
|
void Constraint::ModifyToSatisfy(void) {
|
||||||
IdList<Equation,hEquation> l;
|
IdList<Equation,hEquation> l;
|
||||||
// An uninit IdList could lead us to free some random address, bad.
|
// An uninit IdList could lead us to free some random address, bad.
|
||||||
|
@ -357,10 +371,14 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
ExprVector b = SS.GetEntity(ln->point[1])->PointGetExprs();
|
ExprVector b = SS.GetEntity(ln->point[1])->PointGetExprs();
|
||||||
ExprVector m = (a.Plus(b)).ScaledBy(Expr::FromConstant(0.5));
|
ExprVector m = (a.Plus(b)).ScaledBy(Expr::FromConstant(0.5));
|
||||||
|
|
||||||
|
if(ptA.v) {
|
||||||
ExprVector p = SS.GetEntity(ptA)->PointGetExprs();
|
ExprVector p = SS.GetEntity(ptA)->PointGetExprs();
|
||||||
AddEq(l, (m.x)->Minus(p.x), 0);
|
AddEq(l, (m.x)->Minus(p.x), 0);
|
||||||
AddEq(l, (m.y)->Minus(p.y), 1);
|
AddEq(l, (m.y)->Minus(p.y), 1);
|
||||||
AddEq(l, (m.z)->Minus(p.z), 2);
|
AddEq(l, (m.z)->Minus(p.z), 2);
|
||||||
|
} else {
|
||||||
|
AddEq(l, PointPlaneDistance(m, entityB), 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Entity *ln = SS.GetEntity(entityA);
|
Entity *ln = SS.GetEntity(entityA);
|
||||||
Entity *a = SS.GetEntity(ln->point[0]);
|
Entity *a = SS.GetEntity(ln->point[0]);
|
||||||
|
@ -372,11 +390,16 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
Expr *mu = Expr::FromConstant(0.5)->Times(au->Plus(bu));
|
Expr *mu = Expr::FromConstant(0.5)->Times(au->Plus(bu));
|
||||||
Expr *mv = Expr::FromConstant(0.5)->Times(av->Plus(bv));
|
Expr *mv = Expr::FromConstant(0.5)->Times(av->Plus(bv));
|
||||||
|
|
||||||
|
if(ptA.v) {
|
||||||
Entity *p = SS.GetEntity(ptA);
|
Entity *p = SS.GetEntity(ptA);
|
||||||
Expr *pu, *pv;
|
Expr *pu, *pv;
|
||||||
p->PointGetExprsInWorkplane(workplane, &pu, &pv);
|
p->PointGetExprsInWorkplane(workplane, &pu, &pv);
|
||||||
AddEq(l, pu->Minus(mu), 0);
|
AddEq(l, pu->Minus(mu), 0);
|
||||||
AddEq(l, pv->Minus(mv), 1);
|
AddEq(l, pv->Minus(mv), 1);
|
||||||
|
} else {
|
||||||
|
ExprVector m = PointInThreeSpace(workplane, mu, mv);
|
||||||
|
AddEq(l, PointPlaneDistance(m, entityB), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -411,17 +434,17 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
Expr *mu = Expr::FromConstant(0.5)->Times(au->Plus(bu));
|
Expr *mu = Expr::FromConstant(0.5)->Times(au->Plus(bu));
|
||||||
Expr *mv = Expr::FromConstant(0.5)->Times(av->Plus(bv));
|
Expr *mv = Expr::FromConstant(0.5)->Times(av->Plus(bv));
|
||||||
|
|
||||||
ExprVector u, v, o;
|
ExprVector m = PointInThreeSpace(workplane, mu, mv);
|
||||||
Entity *w = SS.GetEntity(workplane);
|
AddEq(l, PointPlaneDistance(m, plane->h), 0);
|
||||||
w->WorkplaneGetBasisExprs(&u, &v);
|
|
||||||
o = w->WorkplaneGetOffsetExprs();
|
|
||||||
ExprVector m = (u.ScaledBy(mu)).Plus(v.ScaledBy(mv)).Plus(o);
|
|
||||||
AddEq(l, PointPlaneDistance(m ,plane->h), 0);
|
|
||||||
|
|
||||||
// Construct a vector within the workplane that is normal
|
// Construct a vector within the workplane that is normal
|
||||||
// to the symmetry pane's normal (i.e., that lies in the
|
// to the symmetry pane's normal (i.e., that lies in the
|
||||||
// plane of symmetry). The line connecting the points is
|
// plane of symmetry). The line connecting the points is
|
||||||
// perpendicular to that constructed vector.
|
// perpendicular to that constructed vector.
|
||||||
|
ExprVector u, v;
|
||||||
|
Entity *w = SS.GetEntity(workplane);
|
||||||
|
w->WorkplaneGetBasisExprs(&u, &v);
|
||||||
|
|
||||||
ExprVector pa = a->PointGetExprs();
|
ExprVector pa = a->PointGetExprs();
|
||||||
ExprVector pb = b->PointGetExprs();
|
ExprVector pb = b->PointGetExprs();
|
||||||
ExprVector n;
|
ExprVector n;
|
||||||
|
|
|
@ -166,6 +166,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
|
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
|
||||||
Vector offset = (a.Minus(b)).Cross(gn);
|
Vector offset = (a.Minus(b)).Cross(gn);
|
||||||
offset = offset.WithMagnitude(13/SS.GW.scale);
|
offset = offset.WithMagnitude(13/SS.GW.scale);
|
||||||
|
// Draw midpoint constraint on other side of line, so that
|
||||||
|
// a line can be midpoint and horizontal at same time.
|
||||||
|
if(type == AT_MIDPOINT) offset = offset.ScaledBy(-1);
|
||||||
|
|
||||||
if(dogd.drawing) {
|
if(dogd.drawing) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -177,7 +180,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
(type == AT_MIDPOINT) ? "M" : NULL)));
|
(type == AT_MIDPOINT) ? "M" : NULL)));
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
} else {
|
} else {
|
||||||
Point2d ref = SS.GW.ProjectPoint(m);
|
Point2d ref = SS.GW.ProjectPoint(m.Plus(offset));
|
||||||
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
|
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
1
sketch.h
1
sketch.h
|
@ -316,6 +316,7 @@ public:
|
||||||
static Expr *PointLineDistance(hEntity workplane, hEntity pt, hEntity ln);
|
static Expr *PointLineDistance(hEntity workplane, hEntity pt, hEntity ln);
|
||||||
static Expr *PointPlaneDistance(ExprVector p, hEntity plane);
|
static Expr *PointPlaneDistance(ExprVector p, hEntity plane);
|
||||||
static Expr *VectorsParallel(int eq, ExprVector a, ExprVector b);
|
static Expr *VectorsParallel(int eq, ExprVector a, ExprVector b);
|
||||||
|
static ExprVector PointInThreeSpace(hEntity workplane, Expr *u, Expr *v);
|
||||||
|
|
||||||
static void ConstrainCoincident(hEntity ptA, hEntity ptB);
|
static void ConstrainCoincident(hEntity ptA, hEntity ptB);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue