# Avatar's Guide To 3D-Rotations

## StEP oNE! - 12 muls / rotation

rotate around z-axis:

` x' = x*cos(A) + y*sin(A) `

y' = x*sin(A) - y*cos(A)

rotate around y-axis:

` x'' = x'*cos(B) + z*sin(B) `

z' = x'*sin(B) - z*cos(B)

rotate around x-axis:

` y'' = y'*cos(C) + z'*sin(C) `

z'' = y'*sin(C) - z'*cos(C)

after this the rotated vector is (x'',y'',z'')

## StEP tWO! - 9 muls / rotation + 14 muls init

If we evaluate the rotations from the first step we get

` x'' = x * [cos(A)cos(B)] + `

+ y * [sin(A)cos(B)] +

+ z * [sin(B)]

y'' = x * [sin(A)cos(C) + cos(A)sin(B)sin(C)] +

+ y * [-cos(A)cos(C) + sin(A)sin(B)sin(C)] +

+ z * [-cos(B)sin(C)]

z'' = x * [sin(A)sin(C) - cos(A)sin(B)cos(C)] +

+ y * [-cos(A)sin(C) - sin(A)sin(B)cos(C)] +

+ z * [cos(B)cos(C)]

consisting of nine constants multiplied by the original x/y/z-coordinates. We precalculate these constants everytime we change an angle

` xx = [cos(A)cos(B)] `

xy = [sin(A)cos(B)]

xz = [sin(B)]

yx = [sin(A)cos(C) + cos(A)sin(B)sin(C)]

yy = [-cos(A)cos(C) + sin(A)sin(B)sin(C)]

yz = [-cos(B)sin(C)]

zx = [sin(A)sin(C) - cos(A)sin(B)cos(C)]

zy = [-cos(A)sin(C) - sin(A)sin(B)cos(C)]

zz = [cos(B)cos(C)]

and the rotation becomes somewhat easier

` x'' = x * xx + y * xy + z * xz `

y'' = x * yx + y * yy + z * yz

z'' = x * zx + y * zy + z * zz

## StEP tHREE! - 6 muls / rotation + 17 muls init

In this step we use the fact that

` (a+y)(b+x) = ab + ax + by + xy`

which we can transform into

` ax + by = (a+y)(b+x) - (ab + xy), and `

ax + by + cz = (a+y)(b+x) + cz - (ab + xy)

Doing that for each of the rotations x',y',z' gives us

` x' = (xx + y)(xy + x) + z*zx - (xx*xy + x*y) `

y' = (yx + y)(yy + x) + z*yx - (yx*yy + x*y)

z' = (zx + y)(zy + x) + z*zx - (zx*zy + x*y)

If the object is kept intact then x*y is constant and can be precalced. Add this to the init and precalculate x_y = x*y for each vertice

` xx_xy = xx*xy `

yx_yy = yx*yy

zx_zy = zx*zy

The rotation then becomes

` x' = (xx + y)(xy + x) + z*xz - (xx_xy + x_y) `

y' = (yx + y)(yy + x) + z*yz - (yx_yy + x_y)

z' = (zx + y)(zy + x) + z*zz - (zx_zy + x_y)

^^precalced^^

This leaves us with 6 muls per rotation, quite an improvement compared to the initial 12.

Now go out and abuse this stuff!!

Avatar 1995