Draw extension lines for angle constraints between line segments.
parent
1098e598ae
commit
07f3ab95e4
|
@ -227,6 +227,13 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) {
|
||||||
return within;
|
return within;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Constraint::DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da) {
|
||||||
|
dir = dir.WithMagnitude(width / cos(angle));
|
||||||
|
dir = dir.RotatedAbout(n, da);
|
||||||
|
LineDrawOrGetDistance(p, p.Plus(dir.RotatedAbout(n, angle)));
|
||||||
|
LineDrawOrGetDistance(p, p.Plus(dir.RotatedAbout(n, -angle)));
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Draw a line with arrows on both ends, and possibly a gap in the middle for
|
// Draw a line with arrows on both ends, and possibly a gap in the middle for
|
||||||
// the dimension. We will use these for most length dimensions. The length
|
// the dimension. We will use these for most length dimensions. The length
|
||||||
|
@ -271,11 +278,8 @@ void Constraint::DoLineWithArrows(Vector ref, Vector a, Vector b,
|
||||||
if(within > 0) LineDrawOrGetDistance(be, be.Plus(seg));
|
if(within > 0) LineDrawOrGetDistance(be, be.Plus(seg));
|
||||||
}
|
}
|
||||||
|
|
||||||
LineDrawOrGetDistance(ae, ae.Plus(arrow.RotatedAbout(n, theta)));
|
DoArrow(ae, arrow, n, 13.0 * pixels, theta, 0.0);
|
||||||
LineDrawOrGetDistance(ae, ae.Plus(arrow.RotatedAbout(n, -theta)));
|
DoArrow(be, arrow.Negated(), n, 13.0 * pixels, theta, 0.0);
|
||||||
arrow = arrow.ScaledBy(-1);
|
|
||||||
LineDrawOrGetDistance(be, be.Plus(arrow.RotatedAbout(n, theta)));
|
|
||||||
LineDrawOrGetDistance(be, be.Plus(arrow.RotatedAbout(n, -theta)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn) {
|
void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn) {
|
||||||
|
@ -323,6 +327,10 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
db = db.ProjectVectorInto(workplane);
|
db = db.ProjectVectorInto(workplane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double px = 1.0 / SS.GW.scale;
|
||||||
|
Vector a1 = a0.Plus(da);
|
||||||
|
Vector b1 = b0.Plus(db);
|
||||||
|
|
||||||
bool skew;
|
bool skew;
|
||||||
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da),
|
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da),
|
||||||
b0, b0.Plus(db), &skew);
|
b0, b0.Plus(db), &skew);
|
||||||
|
@ -332,12 +340,13 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
// We draw in a coordinate system centered at the intersection point.
|
// We draw in a coordinate system centered at the intersection point.
|
||||||
// One basis vector is da, and the other is normal to da and in
|
// One basis vector is da, and the other is normal to da and in
|
||||||
// the plane that contains our lines (so normal to its normal).
|
// the plane that contains our lines (so normal to its normal).
|
||||||
Vector dna = (da.Cross(db)).Cross(da);
|
Vector norm = da.Cross(db);
|
||||||
da = da.WithMagnitude(1); dna = dna.WithMagnitude(1);
|
Vector dna = norm.Cross(da).WithMagnitude(1.0);
|
||||||
|
da = da.WithMagnitude(1);
|
||||||
|
|
||||||
Vector rm = (*ref).Minus(pi);
|
Vector rm = (*ref).Minus(pi);
|
||||||
double rda = rm.Dot(da), rdna = rm.Dot(dna);
|
double rda = rm.Dot(da), rdna = rm.Dot(dna);
|
||||||
double r = sqrt(rda*rda + rdna*rdna);
|
double r = max(sqrt(rda*rda + rdna*rdna), 15.0 * px);
|
||||||
double c = (da.Dot(db))/(da.Magnitude()*db.Magnitude());
|
double c = (da.Dot(db))/(da.Magnitude()*db.Magnitude());
|
||||||
double thetaf = acos(c);
|
double thetaf = acos(c);
|
||||||
|
|
||||||
|
@ -348,6 +357,8 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector prev = da.ScaledBy(r).Plus(pi);
|
Vector prev = da.ScaledBy(r).Plus(pi);
|
||||||
|
Vector apa = prev;
|
||||||
|
|
||||||
int i, n = 30;
|
int i, n = 30;
|
||||||
for(i = 0; i <= n; i++) {
|
for(i = 0; i <= n; i++) {
|
||||||
double theta = (i*thetaf)/n;
|
double theta = (i*thetaf)/n;
|
||||||
|
@ -357,6 +368,20 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
prev = p;
|
prev = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector apb = prev;
|
||||||
|
DoLineExtend(a0, a1, apa, 5.0 * px);
|
||||||
|
DoLineExtend(b0, b1, apb, 5.0 * px);
|
||||||
|
|
||||||
|
double arrowW = 13 * px;
|
||||||
|
double arrowA = 18.0 * PI / 180.0;
|
||||||
|
|
||||||
|
// Draw arrows only when we have enough space.
|
||||||
|
if(apb.Minus(apa).Magnitude() > 2.5 * arrowW) {
|
||||||
|
double angleCorr = arrowW / (2.0 * r);
|
||||||
|
DoArrow(apa, dna, norm, arrowW, arrowA, angleCorr);
|
||||||
|
DoArrow(apb, dna, norm, arrowW, arrowA, thetaf + PI - angleCorr);
|
||||||
|
}
|
||||||
|
|
||||||
// The elliptical approximation isn't exactly right, but the correct
|
// The elliptical approximation isn't exactly right, but the correct
|
||||||
// calculation (against the bounding box of the text) would be rather
|
// calculation (against the bounding box of the text) would be rather
|
||||||
// complex and this looks pretty good.
|
// complex and this looks pretty good.
|
||||||
|
@ -396,6 +421,35 @@ bool Constraint::IsVisible() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Constraint::DoLineExtend(Vector p0, Vector p1, Vector pt, double salient) {
|
||||||
|
Vector dir = p1.Minus(p0);
|
||||||
|
double k = dir.Dot(pt.Minus(p0)) / dir.Dot(dir);
|
||||||
|
Vector ptOnLine = p0.Plus(dir.ScaledBy(k));
|
||||||
|
|
||||||
|
// Draw projection line.
|
||||||
|
LineDrawOrGetDistance(pt, ptOnLine);
|
||||||
|
|
||||||
|
// Calculate salient direction.
|
||||||
|
Vector sd = dir.WithMagnitude(1.0).ScaledBy(salient);
|
||||||
|
|
||||||
|
Vector from;
|
||||||
|
Vector to;
|
||||||
|
|
||||||
|
if(k < 0.0) {
|
||||||
|
from = p0;
|
||||||
|
to = ptOnLine.Minus(sd);
|
||||||
|
} else if(k > 1.0) {
|
||||||
|
from = p1;
|
||||||
|
to = ptOnLine.Plus(sd);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw extension line.
|
||||||
|
LineDrawOrGetDistance(from, to);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
|
|
||||||
if(!IsVisible()) return;
|
if(!IsVisible()) return;
|
||||||
|
@ -656,16 +710,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
Entity *c = SK.GetEntity(entityC);
|
Entity *c = SK.GetEntity(entityC);
|
||||||
Entity *d = SK.GetEntity(entityD);
|
Entity *d = SK.GetEntity(entityD);
|
||||||
|
|
||||||
Vector a0 = a->VectorGetRefPoint();
|
Vector a0 = a->VectorGetStartPoint();
|
||||||
Vector b0 = b->VectorGetRefPoint();
|
Vector b0 = b->VectorGetStartPoint();
|
||||||
Vector c0 = c->VectorGetRefPoint();
|
Vector c0 = c->VectorGetStartPoint();
|
||||||
Vector d0 = d->VectorGetRefPoint();
|
Vector d0 = d->VectorGetStartPoint();
|
||||||
Vector da = a->VectorGetNum();
|
Vector da = a->VectorGetNum();
|
||||||
Vector db = b->VectorGetNum();
|
Vector db = b->VectorGetNum();
|
||||||
Vector dc = c->VectorGetNum();
|
Vector dc = c->VectorGetNum();
|
||||||
Vector dd = d->VectorGetNum();
|
Vector dd = d->VectorGetNum();
|
||||||
|
|
||||||
if(other) da = da.ScaledBy(-1);
|
if(other) {
|
||||||
|
a0 = a0.Plus(da);
|
||||||
|
da = da.ScaledBy(-1);
|
||||||
|
}
|
||||||
|
|
||||||
DoArcForAngle(a0, da, b0, db,
|
DoArcForAngle(a0, da, b0, db,
|
||||||
da.WithMagnitude(40/SS.GW.scale), &ref);
|
da.WithMagnitude(40/SS.GW.scale), &ref);
|
||||||
|
@ -679,11 +736,14 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
Entity *a = SK.GetEntity(entityA);
|
Entity *a = SK.GetEntity(entityA);
|
||||||
Entity *b = SK.GetEntity(entityB);
|
Entity *b = SK.GetEntity(entityB);
|
||||||
|
|
||||||
Vector a0 = a->VectorGetRefPoint();
|
Vector a0 = a->VectorGetStartPoint();
|
||||||
Vector b0 = b->VectorGetRefPoint();
|
Vector b0 = b->VectorGetStartPoint();
|
||||||
Vector da = a->VectorGetNum();
|
Vector da = a->VectorGetNum();
|
||||||
Vector db = b->VectorGetNum();
|
Vector db = b->VectorGetNum();
|
||||||
if(other) da = da.ScaledBy(-1);
|
if(other) {
|
||||||
|
a0 = a0.Plus(da);
|
||||||
|
da = da.ScaledBy(-1);
|
||||||
|
}
|
||||||
|
|
||||||
Vector ref;
|
Vector ref;
|
||||||
DoArcForAngle(a0, da, b0, db, disp.offset, &ref);
|
DoArcForAngle(a0, da, b0, db, disp.offset, &ref);
|
||||||
|
|
|
@ -688,8 +688,10 @@ public:
|
||||||
void DrawOrGetDistance(Vector *labelPos);
|
void DrawOrGetDistance(Vector *labelPos);
|
||||||
double EllipticalInterpolation(double rx, double ry, double theta);
|
double EllipticalInterpolation(double rx, double ry, double theta);
|
||||||
std::string Label(void);
|
std::string Label(void);
|
||||||
|
bool DoLineExtend(Vector p0, Vector p1, Vector pt, double salient);
|
||||||
void DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
void DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||||
Vector offset, Vector *ref);
|
Vector offset, Vector *ref);
|
||||||
|
void DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da);
|
||||||
void DoLineWithArrows(Vector ref, Vector a, Vector b, bool onlyOneExt);
|
void DoLineWithArrows(Vector ref, Vector a, Vector b, bool onlyOneExt);
|
||||||
int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b);
|
int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b);
|
||||||
void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu);
|
void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu);
|
||||||
|
|
Loading…
Reference in New Issue