Display angle in the middle of its dimension line, not adjacent.

Less visual clutter and more consistency with distance constraints.
This commit is contained in:
EvilSpirit 2016-04-13 08:45:52 +06:00 committed by whitequark
parent 07f3ab95e4
commit 92f5bd450c
2 changed files with 61 additions and 56 deletions

View File

@ -41,14 +41,6 @@ static void LineCallback(void *fndata, Vector a, Vector b)
c->LineDrawOrGetDistance(a, b); c->LineDrawOrGetDistance(a, b);
} }
double Constraint::EllipticalInterpolation(double rx, double ry, double theta) {
double ex = rx*cos(theta);
double ey = ry*sin(theta);
double v = sqrt(ex*ex + ey*ey);
return v;
}
std::string Constraint::Label(void) { std::string Constraint::Label(void) {
std::string result; std::string result;
if(type == ANGLE) { if(type == ANGLE) {
@ -148,7 +140,7 @@ void Constraint::DoProjectedPoint(Vector *r) {
// the line to almost meet the box, and return either positive or negative, // the line to almost meet the box, and return either positive or negative,
// depending whether that extension was from A or from B. // depending whether that extension was from A or from B.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) { int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend) {
hStyle hs = disp.style; hStyle hs = disp.style;
if(hs.v == 0) hs.v = Style::CONSTRAINT; if(hs.v == 0) hs.v = Style::CONSTRAINT;
double th = Style::TextHeight(hs); double th = Style::TextHeight(hs);
@ -160,6 +152,11 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) {
double swidth = ssglStrWidth(s, th) + 4*pixels, double swidth = ssglStrWidth(s, th) + 4*pixels,
sheight = ssglStrCapHeight(th) + 8*pixels; sheight = ssglStrCapHeight(th) + 8*pixels;
return DoLineTrimmedAgainstBox(ref, a, b, extend, gr, gu, swidth, sheight);
}
int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend,
Vector gr, Vector gu, double swidth, double sheight) {
struct { struct {
Vector n; Vector n;
double d; double d;
@ -194,37 +191,43 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) {
tmax = max(t, tmax); tmax = max(t, tmax);
} }
int within = 0; // Both in range; so there's pieces of the line on both sides of the label box.
if(tmin >= 0.0 && tmin <= 1.0 && tmax >= 0.0 && tmax <= 1.0) {
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
return 0;
}
if(tmin > -0.01 && tmin < 1.01 && tmax > -0.01 && tmax < 1.01) { // Only one intersection in range; so the box is right on top of the endpoint
// Both in range; so there's pieces of the line on both sides of the if(tmin >= 0.0 && tmin <= 1.0) {
// label box.
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin))); LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b); return 0;
} else if(tmin > -0.01 && tmin < 1.01) { }
// Only one intersection in range; so the box is right on top of the
// endpoint
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
} else if(tmax > -0.01 && tmax < 1.01) {
// Likewise. // Likewise.
if(tmax >= 0.0 && tmax <= 1.0) {
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b); LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
} else { return 0;
}
// The line does not intersect the label; so the line should get // The line does not intersect the label; so the line should get
// extended to just barely meet the label. // extended to just barely meet the label.
if(tmin < 0.01 && tmax < 0.01) {
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
within = 1;
} else if(tmin > 0.99 && tmax > 0.99) {
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
within = -1;
} else {
// This will happen if the entire line lies within the box.
LineDrawOrGetDistance(a, b);
}
}
// 0 means the label lies within the line, negative means it's outside // 0 means the label lies within the line, negative means it's outside
// and closer to b, positive means outside and closer to a. // and closer to b, positive means outside and closer to a.
return within; if(tmax < 0.0) {
if(extend) a = a.Plus(dl.ScaledBy(tmax));
LineDrawOrGetDistance(a, b);
return 1;
}
if(tmin > 1.0) {
if(extend) b = a.Plus(dl.ScaledBy(tmin));
LineDrawOrGetDistance(a, b);
return -1;
}
// This will happen if the entire line lies within the box.
return 0;
} }
void Constraint::DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da) { void Constraint::DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da) {
@ -315,10 +318,10 @@ void Constraint::DoEqualRadiusTicks(hEntity he) {
} }
void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db, void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
Vector offset, Vector *ref) Vector offset, Vector *ref, bool trim)
{ {
Vector gr = SS.GW.projRight.ScaledBy(1/SS.GW.scale); Vector gr = SS.GW.projRight.ScaledBy(1.0);
Vector gu = SS.GW.projUp.ScaledBy(1/SS.GW.scale); Vector gu = SS.GW.projUp.ScaledBy(1.0);
if(workplane.v != Entity::FREE_IN_3D.v) { if(workplane.v != Entity::FREE_IN_3D.v) {
a0 = a0.ProjectInto(workplane); a0 = a0.ProjectInto(workplane);
@ -356,6 +359,14 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
da = da.ScaledBy(-1); dna = dna.ScaledBy(-1); da = da.ScaledBy(-1); dna = dna.ScaledBy(-1);
} }
hStyle hs = disp.style;
if(hs.v == 0) hs.v = Style::CONSTRAINT;
double th = Style::TextHeight(hs);
double swidth = ssglStrWidth(Label(), th) + 4.0 * px;
double sheight = ssglStrCapHeight(th) + 8.0 * px;
double textR = sqrt(swidth * swidth + sheight * sheight) / 2.0;
*ref = pi.Plus(rm.WithMagnitude(std::max(rm.Magnitude(), 15 * px + textR)));
Vector prev = da.ScaledBy(r).Plus(pi); Vector prev = da.ScaledBy(r).Plus(pi);
Vector apa = prev; Vector apa = prev;
@ -364,7 +375,11 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
double theta = (i*thetaf)/n; double theta = (i*thetaf)/n;
Vector p = da. ScaledBy(r*cos(theta)).Plus( Vector p = da. ScaledBy(r*cos(theta)).Plus(
dna.ScaledBy(r*sin(theta))).Plus(pi); dna.ScaledBy(r*sin(theta))).Plus(pi);
if(trim) {
DoLineTrimmedAgainstBox(*ref, prev, p, false, gr, gu, swidth, sheight);
} else {
LineDrawOrGetDistance(prev, p); LineDrawOrGetDistance(prev, p);
}
prev = p; prev = p;
} }
@ -381,16 +396,6 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
DoArrow(apa, dna, norm, arrowW, arrowA, angleCorr); DoArrow(apa, dna, norm, arrowW, arrowA, angleCorr);
DoArrow(apb, dna, norm, arrowW, arrowA, thetaf + PI - angleCorr); DoArrow(apb, dna, norm, arrowW, arrowA, thetaf + PI - angleCorr);
} }
// The elliptical approximation isn't exactly right, but the correct
// calculation (against the bounding box of the text) would be rather
// complex and this looks pretty good.
double tl = atan2(rm.Dot(gu), rm.Dot(gr));
double adj = EllipticalInterpolation(
ssglStrWidth(Label(), Style::DefaultTextHeight())/2,
ssglStrHeight(Style::DefaultTextHeight())/2,
tl);
*ref = (*ref).Plus(rm.WithMagnitude(adj + 3/SS.GW.scale));
} else { } else {
// The lines are skew; no wonderful way to illustrate that. // The lines are skew; no wonderful way to illustrate that.
*ref = a0.Plus(b0); *ref = a0.Plus(b0);
@ -399,7 +404,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
Vector trans = Vector trans =
(*ref).Plus(gu.ScaledBy(-1.5*ssglStrCapHeight(Style::DefaultTextHeight()))); (*ref).Plus(gu.ScaledBy(-1.5*ssglStrCapHeight(Style::DefaultTextHeight())));
ssglWriteTextRefCenter("angle between skew lines", Style::DefaultTextHeight(), ssglWriteTextRefCenter("angle between skew lines", Style::DefaultTextHeight(),
trans, gr, gu, LineCallback, this); trans, gr.WithMagnitude(px), gu.WithMagnitude(px), LineCallback, this);
} }
} }
@ -725,9 +730,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
DoArcForAngle(a0, da, b0, db, DoArcForAngle(a0, da, b0, db,
da.WithMagnitude(40/SS.GW.scale), &ref); da.WithMagnitude(40/SS.GW.scale), &ref, /*trim=*/false);
DoArcForAngle(c0, dc, d0, dd, DoArcForAngle(c0, dc, d0, dd,
dc.WithMagnitude(40/SS.GW.scale), &ref); dc.WithMagnitude(40/SS.GW.scale), &ref, /*trim=*/false);
break; break;
} }
@ -746,7 +751,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
} }
Vector ref; Vector ref;
DoArcForAngle(a0, da, b0, db, disp.offset, &ref); DoArcForAngle(a0, da, b0, db, disp.offset, &ref, /*trim=*/true);
DoLabel(ref, labelPos, gr, gu); DoLabel(ref, labelPos, gr, gu);
break; break;
} }

View File

@ -686,14 +686,14 @@ public:
void LineDrawOrGetDistance(Vector a, Vector b); void LineDrawOrGetDistance(Vector a, Vector b);
bool IsVisible() const; bool IsVisible() const;
void DrawOrGetDistance(Vector *labelPos); void DrawOrGetDistance(Vector *labelPos);
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); 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, bool trim);
void DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da); 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, bool extend, Vector gr, Vector gu, double swidth, double sheight);
int DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend = true);
void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu); void DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu);
void StippledLine(Vector a, Vector b); void StippledLine(Vector a, Vector b);
void DoProjectedPoint(Vector *p); void DoProjectedPoint(Vector *p);