Fix my rotation-matrix-to-quaternion code: it broke when the

diagonal elements of the matrix summed to -1. Now it's ugly, but I
think that it's correct. And add a command to flip the view to the
other side, which is what started my problems. And tweak display of
H and V and M for constraints: put them in the constraint plane, so
that they're stationary as you rotate around.

[git-p4: depot-paths = "//depot/solvespace/": change = 1704]
This commit is contained in:
Jonathan Westhues 2008-05-02 19:33:35 -08:00
parent 30636a6f29
commit 01885736e6
5 changed files with 54 additions and 8 deletions

View File

@ -159,12 +159,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
case HORIZONTAL: case HORIZONTAL:
case VERTICAL: case VERTICAL:
if(entityA.v) { if(entityA.v) {
Vector r, u, n;
if(workplane.v == Entity::FREE_IN_3D.v) {
r = gr; u = gu; n = gn;
} else {
SS.GetEntity(workplane)->WorkplaneGetBasisVectors(&r, &u);
n = r.Cross(u);
}
// For "at midpoint", this branch is always taken. // For "at midpoint", this branch is always taken.
Entity *e = SS.GetEntity(entityA); Entity *e = SS.GetEntity(entityA);
Vector a = SS.GetEntity(e->point[0])->PointGetCoords(); Vector a = SS.GetEntity(e->point[0])->PointGetCoords();
Vector b = SS.GetEntity(e->point[1])->PointGetCoords(); Vector b = SS.GetEntity(e->point[1])->PointGetCoords();
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5)); Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
Vector offset = (a.Minus(b)).Cross(gn); Vector offset = (a.Minus(b)).Cross(n);
offset = offset.WithMagnitude(13/SS.GW.scale); offset = offset.WithMagnitude(13/SS.GW.scale);
// Draw midpoint constraint on other side of line, so that // Draw midpoint constraint on other side of line, so that
// a line can be midpoint and horizontal at same time. // a line can be midpoint and horizontal at same time.
@ -173,7 +180,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
if(dogd.drawing) { if(dogd.drawing) {
glPushMatrix(); glPushMatrix();
glxTranslatev(m.Plus(offset)); glxTranslatev(m.Plus(offset));
glxOntoWorkplane(gr, gu); glxOntoWorkplane(r, u);
glxWriteTextRefCenter( glxWriteTextRefCenter(
(type == HORIZONTAL) ? "H" : ( (type == HORIZONTAL) ? "H" : (
(type == VERTICAL) ? "V" : ( (type == VERTICAL) ? "V" : (

View File

@ -238,7 +238,7 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b) {
// anything else at the "same" depth in the z-buffer, so that it // anything else at the "same" depth in the z-buffer, so that it
// goes in front of the shaded stuff. // goes in front of the shaded stuff.
Vector n = SS.GW.projRight.Cross(SS.GW.projUp); Vector n = SS.GW.projRight.Cross(SS.GW.projUp);
n = n.WithMagnitude(1.2/SS.GW.scale); n = n.WithMagnitude(3/SS.GW.scale);
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
glxVertex3v(a.Plus(n)); glxVertex3v(a.Plus(n));
glxVertex3v(b.Plus(n)); glxVertex3v(b.Plus(n));

View File

@ -31,6 +31,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView }, { 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView },
{ 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, { 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView },
{ 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, { 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView },
{ 1, "Onto Othe&r Side\tCtrl+O", MNU_OTHER_SIDE, 'R'|C, mView },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
{ 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView }, { 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
@ -185,6 +186,15 @@ void GraphicsWindow::MenuView(int id) {
case MNU_ZOOM_TO_FIT: case MNU_ZOOM_TO_FIT:
break; break;
case MNU_OTHER_SIDE: {
Quaternion quatf = Quaternion::MakeFrom(
SS.GW.projRight.ScaledBy(-1), SS.GW.projUp.ScaledBy(1));
Vector ru = quatf.RotationU();
Vector rv = quatf.RotationV();
SS.GW.AnimateOnto(quatf, SS.GW.offset);
break;
}
case MNU_SHOW_TEXT_WND: case MNU_SHOW_TEXT_WND:
SS.GW.showTextWindow = !SS.GW.showTextWindow; SS.GW.showTextWindow = !SS.GW.showTextWindow;
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();

1
ui.h
View File

@ -91,6 +91,7 @@ public:
MNU_ZOOM_IN, MNU_ZOOM_IN,
MNU_ZOOM_OUT, MNU_ZOOM_OUT,
MNU_ZOOM_TO_FIT, MNU_ZOOM_TO_FIT,
MNU_OTHER_SIDE,
MNU_SHOW_TEXT_WND, MNU_SHOW_TEXT_WND,
MNU_UNITS_INCHES, MNU_UNITS_INCHES,
MNU_UNITS_MM, MNU_UNITS_MM,

View File

@ -37,11 +37,37 @@ Quaternion Quaternion::MakeFrom(Vector u, Vector v)
Vector n = u.Cross(v); Vector n = u.Cross(v);
Quaternion q; Quaternion q;
q.a = 0.5*sqrt(1 + u.x + v.y + n.z); double s, tr = 1 + u.x + v.y + n.z;
q.b = (1/(4*(q.a)))*(v.z - n.y); if(tr > 1e-4) {
q.c = (1/(4*(q.a)))*(n.x - u.z); s = 2*sqrt(tr);
q.d = (1/(4*(q.a)))*(u.y - v.x); q.a = s/4;
return q; q.b = (v.z - n.y)/s;
q.c = (n.x - u.z)/s;
q.d = (u.y - v.x)/s;
} else {
double m = max(u.x, max(v.y, n.z));
if(m == u.x) {
s = 2*sqrt(1 + u.x - v.y - n.z);
q.a = (v.z - n.y)/s;
q.b = s/4;
q.c = (u.y + v.x)/s;
q.d = (n.x + u.z)/s;
} else if(m == v.y) {
s = 2*sqrt(1 - u.x + v.y - n.z);
q.a = (n.x - u.z)/s;
q.b = (u.y + v.x)/s;
q.c = s/4;
q.d = (v.z + n.y)/s;
} else if(m == n.z) {
s = 2*sqrt(1 - u.x - v.y + n.z);
q.a = (u.y - v.x)/s;
q.b = (n.x + u.z)/s;
q.c = (v.z + n.y)/s;
q.d = s/4;
} else oops();
}
return q.WithMagnitude(1);
} }
Quaternion Quaternion::Plus(Quaternion y) { Quaternion Quaternion::Plus(Quaternion y) {
@ -194,6 +220,8 @@ Vector Vector::RotatedAbout(Vector axis, double theta) {
double c = cos(theta); double c = cos(theta);
double s = sin(theta); double s = sin(theta);
axis = axis.WithMagnitude(1);
Vector r; Vector r;
r.x = (x)*(c + (1 - c)*(axis.x)*(axis.x)) + r.x = (x)*(c + (1 - c)*(axis.x)*(axis.x)) +