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