With three.js, I use a quaternion to rotate an arrow (located on the unit sphere).
I have a complete script in this link: https://jsfiddle.net/PhilipZhu/937wov02/1/
Most of the codes are for setups. The relavant parts are typed below:
// define a quaternion
let u = -0.3; // scaling factor of non-unit quaternion
let t = 0.25*Math.PI; // rotate by angle 2*t
let w = Math.exp(u)*Math.cos(t);
let x = Math.exp(u)*Math.sin(t);
let y = 0;
let z = 0;
let q = { w: w, x: x, y: y, z: z };
The above code sets up a quaternion that rotates around x-axis by 2*t
, and the quaternion is scaled by exp(u)
. That means when u=0
, q is a unit quaternion.
// define an arrow shape
const points = [];
points.push( new THREE.Vector3( 0 , 1 , 0 ) );
...
points.push( new THREE.Vector3( 0 , 1 , 0 ) );
These points traces an arrow shape located on the unit sphere.
// Method 1: apply quaternion to Vector3 (blue)
let transformedPoints = points.map((point) => {
return point.clone().applyQuaternion(quaternion);
});
const arrowMaterial1 = new THREE.LineBasicMaterial({color: 0x0000ff});
const geometry1 = new THREE.BufferGeometry().setFromPoints( transformedPoints );
const arrow1 = new THREE.Line( geometry1, arrowMaterial1 );
arrow1.position.set(0, 0, 0);
scene.add(arrow1);
// Method 2: apply quaternion to Object3 (green)
const arrowMaterial2 = new THREE.LineBasicMaterial({color: 0x00ff00});
const geometry2 = new THREE.BufferGeometry().setFromPoints( points );
const arrow2 = new THREE.Line( geometry2, arrowMaterial2 );
arrow2.position.set(0, 0, 0);
arrow2.setRotationFromQuaternion(quaternion);
scene.add(arrow2);
My main question is, the above method 1 and method 2 gives to different shapes when q is non-unitary.
Method 1 copies geometry data to (three.js) Vector3 objects and then apply the quaternion to Vector3, and this method gives intuitive outcome: rotated by expected angle and scaled with respect to the origin.
Method 2 sets a (three.js) Object3 object and then apply the quaternion to Ojbect3. This gives an unintuitive outcome that is different than what method 1 gives.
What is the reason (if there is any) behind it? or is it a bug that no one cares since non-unit quaternion transformation is not common at all?