# Rotation using Quaternions

What’s happening is that when I’m facing in one direction the rotations take place properly, but as soon as I face in another direction the rotations become opposite to the direction I want, and also the vector rotates a bit and then reverses direction of rotation. Any explanation?

Btw I’m using Andrew Stacey’s Quaternions library, so you’ll need that.

Here’s an example.

``````import.library({"Quaternion"})

function setup()
local img = readImage("Cargo Bot:Codea Icon")
m = mesh()
local i = m:addRect(0,0,img.width,img.height)
m:setRectTex(i,0,0,1,1)
m.texture = img

dirn = vec3(0,0,-1)
parameter.boolean("ChangeDirn", false, function() if ChangeDirn then dirn = vec3(0,0,1)
else
dirn = vec3(0,0,-1) end end)

parameter.watch("dirn")
end

function draw()
background(255, 255, 255, 255)

perspective(45,WIDTH/HEIGHT)

l = dirn*500

if ChangeDirn then
camera(0,0,-2000,l.x,l.y,l.z,0,1,0)
else
camera(0,0,0,l.x,l.y,l.z,0,1,0)
end

translate(0,0,-1000)
m:draw()
end

function touched(touch)
if touch.state ~= BEGAN then
local s = vec2(touch.x, touch.y) - vec2(touch.prevX, touch.prevY)
s = s/300
local ls = s:len()
local S = vec3(s.x, s.y, math.sqrt(1 - ls))
local E = vec3(0,0,1)

local q = S:rotateTo(E)
q = q^3
dirn = dirn^q
end
end
``````

I’ll take a look. I’ve been working on quaternions a bit recently with Ignatz so I should be able to figure this out for you (if no-one else gets there first).

Okay. Thanks!!

Just in case someone finds it useful, here’s how I did it(finally).

Calculated quaternion(q) to rotate dirn to z axis, calculated quaternion (p) required to rotate it in direction of deltaX,deltaY vector2 and then rotated the z axis using p then q inverse to get the final dirn.

``````if dirn.z < 0 then
local q = dirn:rotateTo(vec3(0,0,-1))
local n = (vec2(-touch.deltaX, -touch.deltaY):rotate(math.pi/2))*math.sin(.005)
local p = Quaternion(math.cos(.005), n.x, n.y, 0)
dirn = (vec3(0,0,-1)^p)^(q^"")
else
local q = dirn:rotateTo(vec3(0,0,1))
local n = (vec2(-touch.deltaX, -touch.deltaY):rotate(math.pi/2))*math.sin(.005)
local p = Quaternion(math.cos(.005), -n.x, n.y, 0)
dirn = (vec3(0,0,1)^p)^(q^"")
end
``````