Newbie stackoverflow participant, newbie 3D programmer, and far from a math wiz... so I'll try to frame this question as clearly as I can, hoping it makes sense, and hoping for an answer that's not a mile over my head.
I've written a very cool app using three.js that lets the user fly through 3D space and explore a solar system. The flight model is loosely based on the Fly.Controller example/extension in the three.js package which taught me to use quaternions for keeping all the axis rotations sensible relative to each other. The flying part all works great.
Here's my dilemma: When using quaternions, how do I deduce the "normal" (I don't know what else to call it) rotation values to determine which direction I am facing? When using quaternions, the "rotation" structure inside the camera object stays at 0,0,0. So, while I can freely fly through space at any angle, I can't figure out how to determine what direction I'm actually facing. Is there a built in three.js function, or other easy way to convert this?
I've found some similar, confusing, pointers on the web, but nothing I can decipher and put to use in three.js. Thanks.
This is a good question.
When an object is in it's default orientation, it can be considered to be looking in the direction of it's internal, positive z-axis. (The exception is the camera, which is looking in the direction of its internal negative z-axis.)
Therefore, when an object is rotated, you can get the direction the object is facing by applying the object's quaternion to a unit vector pointing in the direction of the positive z-axis (negative z-axis for the camera).
var zVec = new THREE.Vector3( 0, 0, 1 );
zVec.applyQuaternion( object.quaternion );
This will return a unit vector pointing in the direction the object is "facing".
If the object is a child of another rotated object, then the situation is more complicated.
EDIT: updated for r.58. Thanks @eshan.
Thanks for the quick response - it wasn't exactly what I was looking for, but I probably didn't know how to ask the question clearly. My specific use-case was that I wanted to draw a 2D map the represented the relative positions of all the objects in my 3D scene, but I wanted to rotate the objects in the map based on the yaw of the camera in the 3D scene - so I needed to know the "angle" that the quaternion-based camera was facing so that I could offset the rotations of the 2D objects on the map accordingly. Seems to work pretty well. I just wish there didn't have to be so many calculations, but at least Javascript is fast.
// Pass the obj.quaternion that you want to convert here:
//*********************************************************
function quatToEuler (q1) {
var pitchYawRoll = new THREE.Vector3();
sqw = q1.w*q1.w;
sqx = q1.x*q1.x;
sqy = q1.y*q1.y;
sqz = q1.z*q1.z;
unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
test = q1.x*q1.y + q1.z*q1.w;
if (test > 0.499*unit) { // singularity at north pole
heading = 2 * Math.atan2(q1.x,q1.w);
attitude = Math.PI/2;
bank = 0;
return;
}
if (test < -0.499*unit) { // singularity at south pole
heading = -2 * Math.atan2(q1.x,q1.w);
attitude = -Math.PI/2;
bank = 0;
return;
}
else {
heading = Math.atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw);
attitude = Math.asin(2*test/unit);
bank = Math.atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw)
}
pitchYawRoll.z = Math.floor(attitude * 1000) / 1000;
pitchYawRoll.y = Math.floor(heading * 1000) / 1000;
pitchYawRoll.x = Math.floor(bank * 1000) / 1000;
return pitchYawRoll;
}
// Then, if I want the specific yaw (rotation around y), I pass the results of
// pitchYawRoll.y into the following to get back the angle in radians which is
// what can be set to the object's rotation.
//*********************************************************
function eulerToAngle(rot) {
var ca = 0;
if (rot > 0)
{ ca = (Math.PI*2) - rot; }
else
{ ca = -rot }
return (ca / ((Math.PI*2)/360)); // camera angle radians converted to degrees
}
来源:https://stackoverflow.com/questions/14167962/how-to-derive-standard-rotations-from-three-js-when-using-quaternions