## Sunday, July 8, 2012

### Arbitrary Rotation in Gladius

‹prev | My Chain | next›

I am having some difficulty panning my Gladius-based spaceship. I actually have it working for the initial view above the Solar System:

The problem is that the panning controls operate around the x- and y-axis as seen from this orientation. If I fly down to the Sun, panning up-and down still works. I can pan up to look at the Earth and Mars as they revolve about the Sun. The problem arises when I pan right or left:

The problem here is that I continue to rotate around the y-axis:

``````        if (controller.states["PanLeft"])
rotation = [0, -space.clock.delta * 0.0005, 0];``````
After rotating my spaceship up to look at the Earth and Mars, the left-right panning should be rotating around the z-axis, not the y-axis. I could solve this particular use case by simply switching the hard-coded axis of rotation:
``````        if (controller.states["PanLeft"])
rotation = [0, -space.clock.delta * 0.0005, 0];``````
I tried unsuccessfully last night get this to work by resetting the spaceships frame of reference. Had that worked, then I could have always rotated about the z-axis.

Tonight, I try something a little more complex. Specifically, I get started trasnlating the Python script from Paul Bourke to JavaScript. I end up with:
``````    function rotate3d(p1, p2, p0, theta) {
var p = math.vector3.subtract(p1, p0)
, q = new math.Vector3()
, N = math.vector3.subtract(p2, p1)
, Nm = Math.sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]);

// rotation axis unit vector
var n = new math.Vector3(N[0]/Nm, N[1]/Nm, N[2]/Nm);

// Matrix common factors
var c = Math.cos(theta)
, t = (1 - Math.cos(theta))
, s = Math.sin(theta)
, X = n[0]
, Y = n[1]
, Z = n[2];

// Matrix 'M'
var d11 = t*X*X + c
, d12 = t*X*Y - s*Z
, d13 = t*X*Z + s*Y
, d21 = t*X*Y + s*Z
, d22 = t*Y*Y + c
, d23 = t*Y*Z - s*X
, d31 = t*X*Z - s*Y
, d32 = t*Y*Z + s*X
, d33 = t*Z*Z + c;

//            |p.x|
// Matrix 'M'*|p.y|
//            |p.z|
q[0] = d11*p[0] + d12*p[1] + d13*p[2];
q[1] = d21*p[0] + d22*p[1] + d23*p[2];
q[2] = d31*p[0] + d32*p[1] + d33*p[2];

return q;
}``````
And it seems to be correct. Tomorrow, I will try to put it to use.

Day #441