Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Detecting change in device orientation

in Questions Posts: 3

I would like to be able to calculate the change in device orientation but can’t figure out to achieve it. Specifically, I want to track changes of camera focus vector, e.g. assuming that if in local coordinates at time 0 camera looks along x axis, find it’s vector representation at time 1 in current (time 1) local coordinate system. I already have gravity vector, so adding compass vector would make it simple, but is compass reading available in codea? Can’t find it, location.course seems to work in very different way. RotatioRate seems promising but what those numbers are: absolute angle changes since last reading, rate of angle change per sec since last reading? Whatever it is, they seem to come as raw data with bias still in?

Thank you


  • dave1707dave1707 Mod
    edited April 2019 Posts: 8,555

    @Rusty Not really sure what you're doing, but Gravity.x, .y, and .z gives a good representation of how the iPad is orientated.

    PS. There's also a location.course variable that's supposed to give a compass reading, but I haven't gotten it to work. I just get -1 which means it's not working. Maybe the iPad needs to be moving a large distance for it to work.

  • SimeonSimeon Admin Mod
    edited April 2019 Posts: 5,400

    @dave1707 it could be the case you get -1 for course (an invalid reading) if your iPad does not have GPS, which the WiFi model does not have

    (It's the direction you're travelling based on location samples over time)

  • dave1707dave1707 Mod
    Posts: 8,555

    @Simeon I thought maybe it could determine the compass direction based on the change in location.latitude and location.longitude if the iPad moved far enough. For instance while moving in a car there would be a large enough change in latitude and longitude.

  • Posts: 3

    Argh! I still can’t figure what RotationRate means: is it speed of rotation in radians per sec around each three axis? What function supplies the result: is it CMRotationRate from CMDeviceMotion?


  • dave1707dave1707 Mod
    edited April 2019 Posts: 8,555

    @Rusty I think RotationRate is radians per draw cycle. I haven't been able to prove that yet with code.

    PS. radians per draw cycle is probable too fast, so that's probably not it.

    PS. Playing around with a program, so far it looks like it's radians per second.

    PS. What I'm seeing with my program is the time it takes to rotate the iPad 90 degrees times the average rotation rate equals 1 radian.

  • dave1707dave1707 Mod
    Posts: 8,555

    @Rusty I may be over complicating things, but what I'm seeing with my program using rotation rate is:

    If I rotate my iPad from 0 to 90 degrees, then the (average rotation rate times the time to rotate it some angle) divided by (some angle divided by 90) gives a value of approx 1.57 . Like I said this is over complicated, but I'm still playing with it.

  • dave1707dave1707 Mod
    Posts: 8,555

    @Rusty Here's a simpler calculation I came up with.

    Average rotation rate times time times 57 gives degrees of rotation.

  • SimeonSimeon Admin Mod
    Posts: 5,400

    @dave1707 that is correct, but I think it only works on iPads which have GPS

  • SimeonSimeon Admin Mod
    Posts: 5,400

    @Rusty it is the rotation rate provided by CMDeviceMotion

  • Posts: 3

    Thanks Dave and Simeon! It start making sense to me now!

  • dave1707dave1707 Mod
    Posts: 8,555

    @Simeon I have a WiFi only iPad and the rotation rate works OK. Is that what you were referring to above about GPS only iPad's.

  • SimeonSimeon Admin Mod
    Posts: 5,400

    @dave1707 that was about location.course — I think that's only on GPS/cellular iPads

  • Posts: 494

    In my vector extension code (available on github) then I have a function that converts the RotationRate to a quat suitable for keeping track of a device's rotation. Namely, if you keep multiplying the current rotation by this quat then the resulting transformation will keep your scene steady in space (within the bounds of accuracy).

    I'm not on my iPad right now, but I have some code that uses it to keep a cube steady. I'll dig it out later.

  • Posts: 494

    This uses RotationRate directly:

    function setup()
        local size = math.min(HEIGHT, WIDTH) / 2
        d = 1000
        m = cubeMesh(size)
        dirz = vec3(0, 0, 1)
        diry = vec3(0, 1, 0)
        dirx = vec3(1,0,0)
        mat = matrix()
    function draw()
        local mat = matrix()
        local dxa = RotationRate.x
        local dya = RotationRate.y
        local dza = RotationRate.z
        mat = mat:rotate(dza, dirz.x,dirz.y,dirz.z)
        mat = mat:rotate(dya, diry.x,diry.y,diry.z)
        mat = mat:rotate(dxa, dirx.x,dirx.y,dirx.z)
        dirx = mult(mat, dirx)
        diry = mult(mat, diry)
        dirz = mult(mat, dirz)
        local x = dirz.x * d
        local y = dirz.y * d
        local z = dirz.z * d
        camera(x, y, z, 0, 0, 0, diry.x, diry.y, diry.z)
    function cubeMesh(size)
        local v = {}
        local c = {}
        for i = 0, 7 do
            local x = (i % 2) * 2 - 1
            local y = (math.floor(i / 2) % 2) * 2 - 1
            local z = (math.floor(i / 4) % 2) * 2 - 1
            v[i] = vec3(x, y, z) * size / 2
            c[i] = color(127 + 127 * x, 127 + 127 * y, 127 + 127 * z)
        local ver = {}
        local col = {}
        for v1 = 1, 3 do
            local v2 = v1 * 3 % 7
            local v3 = 7 - v1
            local v4 = 7 - v2
            local vt = {v[0], v[v1], v[v2], v[0], v[v3], v[v4], 
                v[7], v[v2], v[v1], v[7], v[v4], v[v3]}
            for i = 1, #vt do
                ver[(v1 - 1) * #vt + i] = vt[i]
            local ct = {c[0], c[v1], c[v2], c[0], c[v3], c[v4], 
                c[7], c[v2], c[v1], c[7], c[v4], c[v3]}
            for i = 1, #ct do
                col[(v1 - 1) * #ct + i] = ct[i]
        local m = mesh()
        m.vertices = ver
        m.colors = col
        return m
    function mult(mat, vec)
        local v1 = mat[1] * vec.x + mat[5] * vec.y + mat[9] * vec.z
        local v2 = mat[2] * vec.x + mat[6] * vec.y + mat[10] * vec.z  
        local v3 = mat[3] * vec.x + mat[7] * vec.y + mat[11] * vec.z
        return vec3(v1, v2, v3)    
Sign In or Register to comment.