Draw projected lines for pt-line-distance constraints in 3d.

pull/144/head
EvilSpirit 2016-12-19 21:54:21 +07:00 committed by whitequark
parent 5763972ed8
commit 727c0a97dc
4 changed files with 40 additions and 18 deletions

View File

@ -44,6 +44,14 @@ void Constraint::DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b)
canvas->DrawLine(a, b, hcs); canvas->DrawLine(a, b, hcs);
} }
void Constraint::DoStippledLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b) {
Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs);
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
strokeStippled.stippleScale = 4.0;
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
DoLine(canvas, hcsStippled, a, b);
}
void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs, void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs,
Vector ref, Vector *labelPos, Vector gr, Vector gu) { Vector ref, Vector *labelPos, Vector gr, Vector gu) {
const Camera &camera = canvas->GetCamera(); const Camera &camera = canvas->GetCamera();
@ -78,14 +86,17 @@ void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs,
if(labelPos) *labelPos = o; if(labelPos) *labelPos = o;
} }
void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) { void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs,
Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs); Vector *r, Vector n, Vector o) {
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH; double d = r->DistanceToPlane(n, o);
strokeStippled.stippleScale = 4.0; Vector p = r->Minus(n.ScaledBy(d));
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled); DoStippledLine(canvas, hcs, p, *r);
*r = p;
}
void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) {
Vector p = r->ProjectInto(workplane); Vector p = r->ProjectInto(workplane);
DoLine(canvas, hcsStippled, p, *r); DoStippledLine(canvas, hcs, p, *r);
*r = p; *r = p;
} }
@ -224,9 +235,6 @@ void Constraint::DoLineWithArrows(Canvas *canvas, Canvas::hStroke hcs,
DoLine(canvas, hcs, a, ae.Plus(out.WithMagnitude(10*pixels))); DoLine(canvas, hcs, a, ae.Plus(out.WithMagnitude(10*pixels)));
if(!onlyOneExt) { if(!onlyOneExt) {
DoLine(canvas, hcs, b, be.Plus(out.WithMagnitude(10*pixels))); DoLine(canvas, hcs, b, be.Plus(out.WithMagnitude(10*pixels)));
} else {
// Vector prj = be;
// DoProjectedPoint(canvas, hcs, &prj);
} }
int within = DoLineTrimmedAgainstBox(canvas, hcs, ref, ae, be); int within = DoLineTrimmedAgainstBox(canvas, hcs, ref, ae, be);
@ -538,11 +546,6 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas,
} }
case Type::PROJ_PT_DISTANCE: { case Type::PROJ_PT_DISTANCE: {
Canvas::Stroke strokeStippled = stroke;
strokeStippled.stipplePattern = StipplePattern::SHORT_DASH;
strokeStippled.stippleScale = 4.0;
Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled);
Vector ap = SK.GetEntity(ptA)->PointGetNum(), Vector ap = SK.GetEntity(ptA)->PointGetNum(),
bp = SK.GetEntity(ptB)->PointGetNum(), bp = SK.GetEntity(ptB)->PointGetNum(),
dp = (bp.Minus(ap)), dp = (bp.Minus(ap)),
@ -554,8 +557,8 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas,
pp = pp.WithMagnitude(1); pp = pp.WithMagnitude(1);
double d = dp.Dot(pp); double d = dp.Dot(pp);
Vector bpp = ap.Plus(pp.ScaledBy(d)); Vector bpp = ap.Plus(pp.ScaledBy(d));
DoLine(canvas, hcsStippled, ap, bpp); DoStippledLine(canvas, hcs, ap, bpp);
DoLine(canvas, hcsStippled, bp, bpp); DoStippledLine(canvas, hcs, bp, bpp);
DoLineWithArrows(canvas, hcs, ref, ap, bpp, /*onlyOneExt=*/false); DoLineWithArrows(canvas, hcs, ref, ap, bpp, /*onlyOneExt=*/false);
DoLabel(canvas, hcs, ref, labelPos, gr, gu); DoLabel(canvas, hcs, ref, labelPos, gr, gu);
@ -612,6 +615,18 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas,
if(!pt.Equals(closest)) { if(!pt.Equals(closest)) {
DoLineWithArrows(canvas, hcs, ref, pt, closest, /*onlyOneExt=*/true); DoLineWithArrows(canvas, hcs, ref, pt, closest, /*onlyOneExt=*/true);
// Draw projected point
Vector a = pt;
Vector b = closest;
Vector ab = a.Minus(b);
Vector ar = a.Minus(ref);
Vector n = ab.Cross(ar);
Vector out = ab.Cross(n).WithMagnitude(1);
out = out.ScaledBy(-out.Dot(ar));
Vector be = b.Plus(out);
Vector np = lA.Minus(pt).Cross(lB.Minus(pt)).WithMagnitude(1.0);
DoProjectedPoint(canvas, hcs, &be, np, pt);
// Extensions to line // Extensions to line
double pixels = 1.0 / camera.scale; double pixels = 1.0 / camera.scale;
Vector refClosest = ref.ClosestPointOnLine(lA, dl); Vector refClosest = ref.ClosestPointOnLine(lA, dl);

View File

@ -83,6 +83,7 @@ public:
Vector DotInToCsys(Vector u, Vector v, Vector n) const; Vector DotInToCsys(Vector u, Vector v, Vector n) const;
Vector ScaleOutOfCsys(Vector u, Vector v, Vector n) const; Vector ScaleOutOfCsys(Vector u, Vector v, Vector n) const;
double DistanceToLine(Vector p0, Vector dp) const; double DistanceToLine(Vector p0, Vector dp) const;
double DistanceToPlane(Vector normal, Vector origin) const;
bool OnLineSegment(Vector a, Vector b, double tol=LENGTH_EPS) const; bool OnLineSegment(Vector a, Vector b, double tol=LENGTH_EPS) const;
Vector ClosestPointOnLine(Vector p0, Vector deltal) const; Vector ClosestPointOnLine(Vector p0, Vector deltal) const;
double Magnitude() const; double Magnitude() const;

View File

@ -683,6 +683,7 @@ public:
void DoLayout(DrawAs how, Canvas *canvas, void DoLayout(DrawAs how, Canvas *canvas,
Vector *labelPos, std::vector<Vector> *refs); Vector *labelPos, std::vector<Vector> *refs);
void DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b); void DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b);
void DoStippledLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b);
bool DoLineExtend(Canvas *canvas, Canvas::hStroke hcs, bool DoLineExtend(Canvas *canvas, Canvas::hStroke hcs,
Vector p0, Vector p1, Vector pt, double salient); Vector p0, Vector p1, Vector pt, double salient);
void DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs, void DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs,
@ -699,8 +700,9 @@ public:
Vector ref, Vector a, Vector b, bool extend = true); Vector ref, Vector a, Vector b, bool extend = true);
void DoLabel(Canvas *canvas, Canvas::hStroke hcs, void DoLabel(Canvas *canvas, Canvas::hStroke hcs,
Vector ref, Vector *labelPos, Vector gr, Vector gu); Vector ref, Vector *labelPos, Vector gr, Vector gu);
void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *p);
Vector *p); void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *p, Vector n, Vector o);
void DoEqualLenTicks(Canvas *canvas, Canvas::hStroke hcs, void DoEqualLenTicks(Canvas *canvas, Canvas::hStroke hcs,
Vector a, Vector b, Vector gn, Vector *refp); Vector a, Vector b, Vector gn, Vector *refp);
void DoEqualRadiusTicks(Canvas *canvas, Canvas::hStroke hcs, void DoEqualRadiusTicks(Canvas *canvas, Canvas::hStroke hcs,

View File

@ -666,6 +666,10 @@ double Vector::DistanceToLine(Vector p0, Vector dp) const {
return ((this->Minus(p0)).Cross(dp)).Magnitude() / m; return ((this->Minus(p0)).Cross(dp)).Magnitude() / m;
} }
double Vector::DistanceToPlane(Vector normal, Vector origin) const {
return this->Dot(normal) - origin.Dot(normal);
}
bool Vector::OnLineSegment(Vector a, Vector b, double tol) const { bool Vector::OnLineSegment(Vector a, Vector b, double tol) const {
if(this->Equals(a, tol) || this->Equals(b, tol)) return true; if(this->Equals(a, tol) || this->Equals(b, tol)) return true;