There is an error in the code I posted earlier. The method qVectorRotator returns an incorrect result when the two argument vectors are antiparallel (or nearly so). Here's a fix; the original code, with the error indicated is shown further down below. private static final double TOLERANCE = 5E-4f; private static final Quat4f Q_IDENTITY = new Quat4f(0f, 0f, 0f, 1f); public static Transform3D vectorRotator(Vector3f ua, Vector3f ub) { Transform3D t = new Transform3D(); t.set(qVectorRotator(ua, ub)); return t; } public static Quat4f qVectorRotator(Vector3f ua, Vector3f ub) { double ang = Math.acos(ua.dot(ub)); if(Math.abs(ang) < TOLERANCE) { return Q_IDENTITY; } Vector3f v = new Vector3f(); float s; if(Math.abs(Math.PI - ang) < TOLERANCE) { v = getPerp(ua); s = 0f; } else { v.cross(ua, ub); v.scale((float) Math.sin(ang/2d)/v.length()); s = (float) Math.cos(ang/2.); } return new Quat4f(v.x, v.y, v.z, s); } public static Vector3f getPerp(Vector3f v) { float x, y, z; x = Math.abs(v.x); y = Math.abs(v.y); z = Math.abs(v.z); Vector3f a; // a points in the positive coordinate that is closest to // orthogonal to v. if(x <= y && x <= z) a = new Vector3f(1f, 0f, 0f); if(y <= z && y <= x) a = new Vector3f(0f, 1f, 0f); if(z <= x && z <= y) a = new Vector3f(0f, 0f, 1f); Vector3f p = new Vector3f(); p.cross(v, a); p.normalize(); return p; } Cheers, KJ On Sat, 7 Jul 2001 06:52:59 -0400, Kynn Jones <[EMAIL PROTECTED]> wrote: > Date: Fri, 6 Jul 2001 22:40:26 -0700 > From: Bob Dengle <[EMAIL PROTECTED]> > Subject: Rotating One Vector Into Another > > Hi > > I have two vector3ds. I want to rotate one so that it falls along the same > line as the other. Does anyone have any suggestions on how to do this? I > know how to compute the angle between the two vectors, but how do I go from > there to a rotation matrix? Thanks in advance. > > B.D. > >Here's how I do it. > > // TOLERANCE is used to decide when the difference between two > // angles is sufficiently close to zero that we may regard them as > // equal. // THIS VALUE FOR TOLERANCE IS TOO SMALL: > private static final double TOLERANCE = 0.00001; > > private static final Quat4f Q_IDENTITY = new Quat4f(0f, 0f, 0f, 1f); > private static final Quat4f Q_NEG_IDENTITY = new Quat4f(0f, 0f, 0f, -1f); > > public static Transform3D vectorRotator(Vector3f ua, Vector3f ub) { > Transform3D t = new Transform3D(); > Quat4f q = qVectorRotator(ua, ub); > > > if(!q.equals(Q_NEG_IDENTITY)) { > t.set(q); > } > else { > // for some reason, t.set(q) gives incorrect results when > // q equals Q_NEG_IDENTITY. > t.setScale(-1f); > } > return t; > } > > public static Quat4f qVectorRotator(Vector3f ua, Vector3f ub) { > double angle = Math.acos(ua.dot(ub)); > if(Math.abs(angle) < TOLERANCE) { > // if the angle subtended by ua and ub is sufficiently small > // we regard them as equal. > return Q_IDENTITY; > } > if(Math.abs(Math.PI - angle) < TOLERANCE) { > // this is the case when ua and ub are collinear but point in > // opposite directions. // THIS IS WRONG: > return Q_NEG_IDENTITY; > } > > Vector3f v = new Vector3f(); > // here we build the quaternion for the general case. > v.cross(ua, ub); > v.scale((float) Math.sin(angle/2d)/v.length()); > return new Quat4f(v.x, v.y, v.z, (float) Math.cos(angle/2.)); > } =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA3D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".