Orientation of an object to the tangent of a spline point in THREE.JS

I use SplineCurve3 to build a line only on the X and Y axis. I have a cube that successfully animates along this line using spline.getPoint(t) where t is 0-1 in time. I am trying to orient the cube to a line through my up vector, which is Y using a point product.

It is almost aligned, but ever so little. I thought that I would use the point product of the vector Y and the tangent of the current point as the angle of rotation of the quaternion k.

Here is my rendering function:

 function render() { var updateMatrix = new THREE.Matrix4(); updateMatrix.setPosition(spline.getPoint(t)); var angle = new THREE.Vector3(0,1,0).dot(spline.getTangent(t).normalize()); var quat = new THREE.Quaternion; quat.setFromAxisAngle(new THREE.Vector3(0,0,1), angle); updateMatrix.setRotationFromQuaternion(quat); marker.rotation.getRotationFromMatrix(updateMatrix); marker.matrixWorld = updateMatrix; t = (t >= 1) ? 0 : t += 0.002; renderer.render(scene, camera); } 

And here is the fiddle demonstrating my problem, can someone tell me where I am wrong in the aspect of rotation?

You can edit mine - jsfiddle example

+5
matrix quaternions
source share
1 answer

As a rule, it is better not to contact object.matrix directly, but simply set the position , rotation and scale object. Let the library handle matrix manipulations. You must have matrixAutoUpdate = true; .

To process part of the rotation, first get the tangent to the curve.

 tangent = spline.getTangent( t ).normalize(); 

You want to rotate the object so that its top vector (local y-vector) points in the direction of the tangent vector of the curve. First calculate the axis to rotate around. An axis is a vector perpendicular to a plane defined by an upward vector and a tangent vector. You use a cross product to get this vector.

 axis.crossVectors( up, tangent ).normalize(); 

Please note that in your case, since the spline lies in a plane perpendicular to the z axis, the calculated axis will be parallel to the z axis. However, it can point in the direction of the positive z axis or the negative z axis - it depends on the direction of the tangent vector.

Now calculate the angle in radians between the up vector and the tangent vector. The dot product of the age vector and the tangent vector give the cosine of the angle between them (since both vectors have a unit length). Then you need to take the arc cosine to get the angle itself.

 radians = Math.acos( up.dot( tangent ) ); 

Now remove the quaternion from the axis and angle.

 marker.quaternion.setFromAxisAngle( axis, radians ); 

EDIT: updated script: http://jsfiddle.net/SCXNQ/891/ for three.js r.69

+10
source share

All Articles