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:
parent
07f3ab95e4
commit
92f5bd450c
|
@ -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) {
|
||||||
if(tmin > -0.01 && tmin < 1.01 && tmax > -0.01 && tmax < 1.01) {
|
|
||||||
// Both in range; so there's pieces of the line on both sides of the
|
|
||||||
// label box.
|
|
||||||
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
|
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
|
||||||
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
||||||
} else if(tmin > -0.01 && tmin < 1.01) {
|
return 0;
|
||||||
// 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.
|
|
||||||
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
|
||||||
} else {
|
|
||||||
// The line does not intersect the label; so the line should get
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only one intersection in range; so the box is right on top of the endpoint
|
||||||
|
if(tmin >= 0.0 && tmin <= 1.0) {
|
||||||
|
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Likewise.
|
||||||
|
if(tmax >= 0.0 && tmax <= 1.0) {
|
||||||
|
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The line does not intersect the label; so the line should get
|
||||||
|
// extended to just barely meet the label.
|
||||||
// 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);
|
||||||
LineDrawOrGetDistance(prev, p);
|
if(trim) {
|
||||||
|
DoLineTrimmedAgainstBox(*ref, prev, p, false, gr, gu, swidth, sheight);
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user