martes, 9 de febrero de 2010

ROTATION OF A SPHERE IN ALL AXES

Universidad La Salle Noroeste

Animación por Computadora IV



Mtro. Enrique Rosales

Guillermo Antonio Aceves Ceballos

09-febrero-2010

ROTATION OF A SPHERE IN ALL AXES



INTRODUCTION

In this paper I’ll explain how to solve the strange movement that makes a sphere in a field when you rotate it in 2 axis at the same time, using quaternions in 3ds Max.



DEVELOPMENT

First we need to create a sphere with any radius and also a plane all in the position (0,0,0). Then we apply a checkers texture to the sphere so when we move the sphere you will notice how the movement is going, if it is rotating the sphere or not. Next we need to link the sphere(child) to the plane(father) to make some moves later.

When you move the sphere and the checkers texture doesn’t changes ,it means the sphere isn’t rotating, so you need to make an expression to help the sphere rotate well when you move it in X. Put the view in local so you can watch how the sphere moves and how is functioning the expression we made.

Next open CURVE EDITOR, select the axis that was rotating when you moved the sphere on the plane in LOCAL view, right click it and select FLOAT EXPRESSION. Then create a new variable called PosX and we assign it to the x position of the plane that is going to be controlled with the ASIGN CONTROLLER option, also we need to assign the radius controller creating another variable and assign it to the radius of the sphere.

You need to write this expression:

degToRad((posX)/(2*pi*radio))*360

First degToRad is a function that changes degrees to radians because 3dMax works with degrees and we need it in radians because the final division well do it in degrees and (posX/2*pi*radio)*360 is an equation that tells us that for each unit that the sphere moves in the X position it will be divided by its perimeter and multiplied by 360 degrees.

With this movement in the plane in X position and the sphere will start rolling on its axis like a wheel. To move it in the Y axis you need to do the same procedure you did with X position so the sphere can move in both directions X and Y , but if you move it in both directions occurs something wrong a problem in the interpolation of the rotation we need to fix. The sphere loses control because the axis overlap because the previous rotations.

This problem is solved with a rotation script which rotation quaternions are removed (complex numbers in 4D using 3dmax to rotate, they are imaginary vectors in 3d where the scale and rotations are stored using some functions senoidals and cosenoidals) and make calculus with them to find the correct rotation and different frames.

The script for the sphere its the next one:

obj = $Sphere01
-- change the name here

timeres = 1f
--time which will make the difference (1frame)

fn getrot t =
-- where the function is created to perform the rotation

(

if t<=0f then return quat 0 0 0 1 -- t=0
-- If no movement returns the quaternion basis (no rotation, because the value is 0) otherwise

t0 = t-timeres
-- you subtract the current time at which requested the timer (first frame)

t1 = t
-- the function is recorded



rot0 = getrot(t0)
-- previous rotation



p0 = at time t0 obj.position
—previous rotation

p1 = at time t1 obj.position
—current rotation

if(p0==p1) then return rot0
– if they return the same value, then there’s no movement



dif = p1-p0
-- subtract positions

len = Length(dif)
-- and the length function will give us the length of the previous subtraction difference

vec = dif / len
-- is the normal vector with the difference between the length



r0 = at time t0 obj.radius
-- previous ratdius

r1 = at time t1 obj.radius
-- current radius



rotax = cross vec [0, 0, 1]
– axis of rotation

angle = 360*len/((r0+r1)*pi)
—amount of rotation in degrees

rotdif = quat angle rotax
-- get the quaternion rotation in the difference between positions

rot1 = rot0 + rotdif
-- total rotation

)



getrot(currentTime)



As we said we need at least 2 different frames in motion since it can require different times. To get the direction of motion we need to subtract the position of the old frame to the new, If we have X = 0 in frame 0, and X = 10 in frame 2, subtract:
10 - 0 = 10 if positive, turns right.
We can also find the unit vector, dividing it by the length of the vector that is the length of the distance the ball crossed.

p0 = at time t0 obj.position
p1 = at time t1 obj.position

dif = p1-p0
len = Length (diff)
vec = diff / len


Then we need to find the axis of rotation. Already with the distance and direction of motion we can get the axis of rotation. Assuming the floor is oriented horizontally, we can say that the force that is applied to the floor area is in the Z axis (gravity). The rotation axis has to be perpendicular to this vector as well, and then with that, we can find the vector of the axis of rotation using a cross product between vectors. 3ds Max already has a function called cross. The function is rotax cross vec = [0,0,1].

To get the quantity of rotation, if the sphere gives a complete turn, it would have to travel a distance equal to its circumference. So if we divide the distance we found prior to its circumference, well find how many rotations has to take to travel that distance. The circumference of a circle is 2 * pi * r. We n to think about the radio changes then well use the average of the2 radius at r0 and r1. So we can get the rotation angle (in degrees) needed to travel a the distance than is angle = 360 * len / ((r0 r1) * pi)


Already with the axis of rotation and the times that is going to be rotated we build the QUATERNION. 3ds Max comes with a function that needs these values
rotax rotdif = quat angle
Rot1 = rot0 rotdif

This quaternion is going to define the rotation of the actual frame, the only way to do this is recording the values in each frame, which is why it is created a function of time called recursively until there are no values to add. If you want more precision you can change the timer to less.

And we resolved the problem.

REFERENCES

1) Http://www.cuneytozdas.com/tutorials/maxscript/
The code and the explanation was written by Tozdas Curney.

2)http://en.wikipedia.org/wiki/Quaternion

No hay comentarios:

Publicar un comentario