Continue an extension arc towards angle constraint label.

This commit is contained in:
EvilSpirit 2016-04-15 17:57:44 +06:00 committed by whitequark
parent 92f5bd450c
commit 3b7e7289c8

View File

@ -343,22 +343,33 @@ 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 norm = da.Cross(db);
Vector dna = norm.Cross(da).WithMagnitude(1.0);
da = da.WithMagnitude(1); da = da.WithMagnitude(1);
db = db.WithMagnitude(1);
Vector rm = (*ref).Minus(pi); Vector norm = da.Cross(db);
double rda = rm.Dot(da), rdna = rm.Dot(dna);
double r = max(sqrt(rda*rda + rdna*rdna), 15.0 * px);
double c = (da.Dot(db))/(da.Magnitude()*db.Magnitude());
double thetaf = acos(c);
Vector dna = norm.Cross(da).WithMagnitude(1.0);
Vector dnb = norm.Cross(db).WithMagnitude(1.0);
// da and db magnitudes are 1.0
double thetaf = acos(da.Dot(db));
// Calculate median
Vector m = da.ScaledBy(cos(thetaf/2)).Plus( Vector m = da.ScaledBy(cos(thetaf/2)).Plus(
dna.ScaledBy(sin(thetaf/2))); dna.ScaledBy(sin(thetaf/2)));
Vector rm = (*ref).Minus(pi);
// Test which side we have to place an arc
if(m.Dot(rm) < 0) { if(m.Dot(rm) < 0) {
da = da.ScaledBy(-1); dna = dna.ScaledBy(-1); da = da.ScaledBy(-1); dna = dna.ScaledBy(-1);
db = db.ScaledBy(-1); dnb = dnb.ScaledBy(-1);
} }
double rda = rm.Dot(da), rdna = rm.Dot(dna);
// Introduce minimal arc radius in pixels
double r = max(sqrt(rda*rda + rdna*rdna), 15.0 * px);
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);
@ -367,23 +378,53 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
double textR = sqrt(swidth * swidth + sheight * sheight) / 2.0; double textR = sqrt(swidth * swidth + sheight * sheight) / 2.0;
*ref = pi.Plus(rm.WithMagnitude(std::max(rm.Magnitude(), 15 * px + textR))); *ref = pi.Plus(rm.WithMagnitude(std::max(rm.Magnitude(), 15 * px + textR)));
Vector prev = da.ScaledBy(r).Plus(pi); // Additional extension angle
Vector apa = prev; double addAngle = 0.0;
int i, n = 30; // Arc extension to db.
for(i = 0; i <= n; i++) { // We have just enlarge angle value.
double theta = (i*thetaf)/n; if(HasLabel() && rm.Dot(dnb) > 0.0) {
Vector p = da. ScaledBy(r*cos(theta)).Plus( // rm direction projected to plane with u = da, v = dna
dna.ScaledBy(r*sin(theta))).Plus(pi); Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0);
if(trim) { // rmp and db magnitudes are 1.0
DoLineTrimmedAgainstBox(*ref, prev, p, false, gr, gu, swidth, sheight); addAngle = acos(rmp.Dot(db));
} else { }
LineDrawOrGetDistance(prev, p);
Vector ru = da;
Vector rv = dna;
// Arc extension to da.
// We are enlarge angle value and rewrite basis to align along rm projection.
if(HasLabel() && rm.Dot(dna) < 0.0) {
// rm direction projected to plane with u = da, v = dna
Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0);
ru = rmp;
rv = norm.Cross(ru).WithMagnitude(1.0);
// rmp and da magnitudes are 1.0
addAngle = acos(rmp.Dot(da));
}
Vector prev;
int n = 30;
for(int i = 0; i <= n; i++) {
double theta = (i*(thetaf + addAngle))/n;
Vector p = ru.ScaledBy(r*cos(theta)).Plus(
rv.ScaledBy(r*sin(theta))).Plus(pi);
if(i > 0) {
if(trim) {
DoLineTrimmedAgainstBox(*ref, prev, p, false, gr, gu, swidth, sheight);
} else {
LineDrawOrGetDistance(prev, p);
}
} }
prev = p; prev = p;
} }
Vector apb = prev; // Arrow points
Vector apa = da. ScaledBy(r).Plus(pi);
Vector apb = da. ScaledBy(r*cos(thetaf)).Plus(
dna.ScaledBy(r*sin(thetaf))).Plus(pi);
DoLineExtend(a0, a1, apa, 5.0 * px); DoLineExtend(a0, a1, apa, 5.0 * px);
DoLineExtend(b0, b1, apb, 5.0 * px); DoLineExtend(b0, b1, apb, 5.0 * px);