3d Rotation With Axis & Angle
Solution 1:
Your approach sounds correct but you don't show what the a, b vectors are and the constant angle is, I'm guessing, just for testing. I did this before so I dug up my code and this is the math I found...
given: originalVec = unit vector pointing up Y axis (direction of cube top/normal) targetVec = white vector
Now you want the axis and angle that will rotate originalVec to align with targetVec. The most direct axis of rotation is perpendicular to both input vectors, so take their cross product. That axis is not a unit vector so also normalise it. The angle to rotate (in radians) is the inverse-cosine of the dot-product.
axis = Vector3.cross(originalVec, targetVec)
axis.normalise
angle = inversecos(Vector3.dot(originalVec, targetVec))
quat = AxisAngle2Quaternion(axis, angle)
rot = Quaternion2Matrix(quat)
cube.matrix = rot
Instead of replacing the cube's matrix I think you want to compose it with the new transform...
cube.matrix.multiplyBy(rot)
...but I'm not 100% sure about that. Also, I've seen implementations where AxisAngle2Quaternion takes an angle in degrees. When the input vectors are parallel or opposite the axis is <0,0,0> so that should be tested for. If the cube rotates the wrong way then the cross-product vector parameters are in the wrong order, I never remember which and just try them both. hth.
Edit I've had a chance to play with Three.js and hacked one of the examples to orient a cube. Comments show where I added stuff and all the orienting math happens in alignCube(). Align and Spin example Mousing up/down moves the target line. Mousing left/right spins on the line.
Scene objects in Three.js seem to all inherit from Object3D which has a autoUpdateMatrix property set true by default. This needs to be set false otherwise the updateMatrix function gets called which recalculates the matrix from the objects position, scale and rotation properties. Alternately you could assign a different updateMatrix function.
It'd be nice if Three.js had some documentation :)
Solution 2:
From Trochoid's example, here's the function that I use to achieve the alignment and spin from the second image:
//object, normalized direction vector, rotation in radiansfunctionalign(target, dir, rot) {
//Three.js uses a Y up coordinate system, so the cube inits with this vectorvar up = newTHREE.Vector3(0, 1, 0);
//euler angle between direction vector and up vectorvar angle = Math.acos(up.dot(dir));
//cross product of the up vector and direction vectorvar axis = newTHREE.Vector3();
axis.cross(up, dir);
axis.normalize();
//rotation to aligns the target with the direction vectorvar rotate = THREE.Matrix4.rotationAxisAngleMatrix(axis, angle);
//rotation around direction vectorvar revolve = THREE.Matrix4.rotationAxisAngleMatrix(dir, rot);
//compose the rotations (order matters, can be done other ways)
revolve.multiplySelf(rotate);
//assign matrix (autoUpdateMatrix = false)
target.matrix = revolve;
}
Solution 3:
Because nobody has a really good solution, I can at least advice you on how to get closer.
There are 3 possible problems and you have one of them:
- The math is not right, or you don't understand it. (Should not be so much a problem here)
- Floating points arithmetics are always a problem for computers (Should also not be a problem, because it is a pretty basic one. If your framework can not deliver a solution, then the framework has no value at all for 3d programming)
- You don't use the framework right
Because it is pretty likely that No. 3 is the case, try finding a mailing list or support forum or whatever for the framework and talk to the people there. They should be able to explain to you, what you do wrong with their framework. Then come back and post the solution here!
Post a Comment for "3d Rotation With Axis & Angle"