[Fluxus] how to get the local rotation of a primitive as a vector??

Dave Griffiths dave at pawfal.org
Tue Jan 26 11:11:05 PST 2010


Hi Rob,

This looks great - it would be good to have boids in the fluxus
examples :)

On Tue, 2010-01-26 at 15:54 +0100, Rob Bothof wrote:
> thanx!
> this is helpful
> 
> For finally setting the rotation i am using the (maim) matrix-aim 
> function, but the birds are still flipping over their backs from time to 
> time
> I've been reading on quaternions but this is still beyond my 
> understanding of 3d math.

I would imagine that the flipping you describe with maim is gimbal
lock[1] occurring. The proper way to avoid these problems is to use
quaternions, but there are often quick hacky ways to solve it. 

Gimbal lock happens when the two vectors given to maim are similar -
where the up vector and forward vector approach (or oppose) each other.
In the past I've managed to get around this by preventing the forward
directions to ever be exactly up or down. 

You might also be able to put a check in your code and switch to another
up vector, but this might also introduce more flipping.

Something else related to this that might be useful to know is that the
top 3 vectors in a matrix are the 3 vectors representing the directions,
eg:

(define (build-line a b)
    (let ((p (build-ribbon 2)))
        (with-primitive p
            (hint-none) (hint-unlit) (hint-wire)
            (pdata-set! "p" 0 a)
            (pdata-set! "p" 1 b)) p))

(define (draw-transform m)
    (wire-colour (vector 1 0 0))
    (build-line (vector 0 0 0) 
        (vector
            (vector-ref m 0)
            (vector-ref m 1)
            (vector-ref m 2)))
    
    (wire-colour (vector 0 1 0))
    (build-line (vector 0 0 0) 
        (vector
            (vector-ref m 4)
            (vector-ref m 5)
            (vector-ref m 6)))
    
    (wire-colour (vector 0 0 1))
    (build-line (vector 0 0 0) 
        (vector
            (vector-ref m 8)
            (vector-ref m 9)
            (vector-ref m 10))))

(clear)

(draw-transform (mident))

(draw-transform 
    (mmul
        (mscale (vector 1 2 1))
        (mrotate (vector 23 40 2))))

cheers,

dave

[1] http://en.wikipedia.org/wiki/Gimbal_lock

> 
> I've build each birdy according to a struct:
> (define-struct Birdy (
>     (pos #:mutable) ; position vector
>     (vel #:mutable) ; velocity vector
>     (mass #:mutable) ; const
>     ....
>     (Oforward #:mutable) ; local x vector
>     (Oup #:mutable) ; local y vector
>     (Oside #:mutable); local z vector
>     ...
>     (body) ; prim
> )
> 
> my failsafe would be to get the orientation from the struct-list of 
> another Birdy
> But with this I can get the local orientation-axisses of an object that 
> is not build with these struct parameters!
> 
> forward-orientation:
> (vtransform-rot (vector 1 0 0) (with-primitive p (get-global-transform)))
> up-orientation:
> (vtransform-rot (vector 0 1 0) (with-primitive p (get-global-transform)))
> side-orientation:
> (vtransform-rot (vector 0 0 1) (with-primitive p (get-global-transform)))
> 
> greets and thanx, Rob
> 
> 
> 
> 
> 
> 
> 
> > hi Rob,
> >
> >> some starting pics: http://www.flickr.com/photos/superrobber/4305067091/
> > looks really nice. congrats.
> >
> >> i've tried the (vtransform-rot) but with this function somehow i just 
> >> can't get the rotation out of the (get-transform) matrix
> >> the manual says it's kinda ment for use with normals ?
> > i believe you can get the direction vector like this:
> >
> > (define (global-dir p)
> >     (vtransform-rot (vector 0 1 0)
> >         (with-primitive p
> >             (get-global-transform))))
> >
> > ; to draw it
> > (let ([dir (global-dir p)])
> >     (with-primitive (build-ribbon 2)
> >         (hint-unlit)
> >         (hint-wire)
> >         (pdata-set! "p" 0 (vector 0 0 0))
> >         (pdata-set! "p" 1 (vmul dir 5))))
> >
> > but i'm not sure that this would be very useful in your case, because 
> > this is just a direction vector and not a rotation vector. if you want 
> > the rotation angles, you can try (matrix->euler). but since you want 
> > to interpolate between rotation matrices, you might need quaternions.
> >
> > best,
> > gabor
> >
> 




More information about the Fluxus mailing list