Inventor - quaternions & collision detection

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Thu, 06 Jan 1994 21:08:04



Hello, I am currently using Inventor (1.01) as 3D-library and I have some
problems. First, I can write a rotation to a SoTransform-node using quaternions.Unfortunately, I can't READ rotations as quaternions. Or that's what my manual
tells me. Is there any way to read quaternions, or do I have to translate these
rotations to quaternions myself?

The second question is somewhat more involved. I am trying to implement
collision detection for Inventor-objects. Has anyone done something like
this before? (I'm not interested in bounding boxes - I need to determine
the exact collisions).

The problem is, that you need a lot of lowlevel information about the
composition of the objects. Do I really need to parse the objects myself and
then apply all transformations as well, or is there a simpler way?

Any answers/pointers to references/hints are *much* appreciated.

Regards,
Ronald Kunenborg.

Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number
Shake your chains to earth like dew,
which in sleep had fallen on ye
Ye are many, they are few.           - Shelley, `The Mask of Anarchy' (1819)
--
Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number             | (International Socialist)
Shake your chains to earth like dew,
which in sleep had fallen on ye

 
 
 

Inventor - quaternions & collision detection

Post by Paul S. Strau » Sun, 09 Jan 1994 05:07:42


|> Hello, I am currently using Inventor (1.01) as 3D-library and I have some
|> problems. First, I can write a rotation to a SoTransform-node using quaternions.Unfortunately, I can't READ rotations as quaternions. Or that's what my manual
|> tells me. Is there any way to read quaternions, or do I have to translate these
|> rotations to quaternions myself?

I'm not sure what you mean by "read." Do you want to specify the
rotations as quaternions in an Inventor file you are typing in?
If so, you can't do that; in files, rotations are always specified
as axis+angle. If you want to specify rotations as quaternions in
a program, the SbRotation class (and the So[SM]FRotation field
classes) let you do so - just pass in the 4 components of the
quaternion. You can also specify rotations as axis+angle or as
a rotation that brings one vector into another. You could use
this program to converts a quaternion to axis+angle if you need
to do that:

        #include <Inventor/SbLinear.h>

        main()
        {
            SbVec3f    axis;
            float      angle;
            SbRotation r(0.0, 1.0, 0.0, 0.5); // 4 components of quaternion
            r.getValue(axis, angle);
            printf("Axis (%g, %g, %g), angle %g\n",
                   axis[0], axis[1], axis[2], angle);
        }

|> The second question is somewhat more involved. I am trying to implement
|> collision detection for Inventor-objects. Has anyone done something like
|> this before? (I'm not interested in bounding boxes - I need to determine
|> the exact collisions).
|>
|> The problem is, that you need a lot of lowlevel information about the
|> composition of the objects. Do I really need to parse the objects myself and
|> then apply all transformations as well, or is there a simpler way?
|>
|> Any answers/pointers to references/hints are *much* appreciated.

Well, with Inventor 1.x, there's no easy way to get back all of the
info you need. You could apply a callback action and do all the work
yourself, depending on each shape type.

The good news is that in Inventor 2.0, there is an extension to the
callback action that lets you get back all triangles in the
tessellated representation of any filled object. This means you would
just have to compare the triangles forming each object.

|> Regards,
|> Ronald Kunenborg.

----

  "A horse walked into a bar and the bartender said, "Why the long face?,"
   and the horse kicked him to death. True story."  - Allan Havey

 
 
 

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Thu, 13 Jan 1994 00:11:56




>|> Hello, I am currently using Inventor (1.01) as 3D-library and I have some
>|> problems. First, I can write a rotation to a SoTransform-node using quaternions.Unfortunately, I can't READ rotations as quaternions. Or that's what my manual
>|> tells me. Is there any way to read quaternions, or do I have to translate these
>|> rotations to quaternions myself?

>I'm not sure what you mean by "read." Do you want to specify the
>rotations as quaternions in an Inventor file you are typing in?
>If so, you can't do that; in files, rotations are always specified
>as axis+angle. If you want to specify rotations as quaternions in
>a program, the SbRotation class (and the So[SM]FRotation field
>classes) let you do so - just pass in the 4 components of the
>quaternion. You can also specify rotations as axis+angle or as
>a rotation that brings one vector into another. You could use
>this program to converts a quaternion to axis+angle if you need
>to do that:

>    #include <Inventor/SbLinear.h>

>    main()
>    {
>        SbVec3f    axis;
>        float      angle;
>        SbRotation r(0.0, 1.0, 0.0, 0.5); // 4 components of quaternion
>        r.getValue(axis, angle);
>        printf("Axis (%g, %g, %g), angle %g\n",
>               axis[0], axis[1], axis[2], angle);
>    }

The problem I have is the old problem that when you read two axis+angle pairs
then interpolate these pairs, you lose one degree of freedom due to a singula-
rity in the Euler angles. In other words, if you interpolate two SbRotations
the resulting rotations 'look funny' in some cases. Interpolating quaternions
solves this problem, since quaternions were designed to eliminate just this
problem.

What I want is : 1) read 4 values of SbRotation 1, then 4 values of SbRot. 2
                    (NOT axis+angle, but 4 components of a quaternion)
                 2) interpolate these 8 values (no problem).

- Show quoted text -

Quote:>|> The second question is somewhat more involved. I am trying to implement
>|> collision detection for Inventor-objects. Has anyone done something like
>|> this before? (I'm not interested in bounding boxes - I need to determine
>|> the exact collisions).
>|>
>|> The problem is, that you need a lot of lowlevel information about the
>|> composition of the objects. Do I really need to parse the objects myself and
>|> then apply all transformations as well, or is there a simpler way?
>|>
>|> Any answers/pointers to references/hints are *much* appreciated.

>Well, with Inventor 1.x, there's no easy way to get back all of the
>info you need. You could apply a callback action and do all the work
>yourself, depending on each shape type.

>The good news is that in Inventor 2.0, there is an extension to the
>callback action that lets you get back all triangles in the
>tessellated representation of any filled object. This means you would
>just have to compare the triangles forming each object.

The bad news is, I'm not going to get access to Inventor 2.0.

>|> Regards,
>|> Ronald Kunenborg.

>----

>  "A horse walked into a bar and the bartender said, "Why the long face?,"
>   and the horse kicked him to death. True story."  - Allan Havey

--
Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number             | (International Socialist)
Shake your chains to earth like dew,
which in sleep had fallen on ye
 
 
 

Inventor - quaternions & collision detection

Post by Paul S. Strau » Thu, 13 Jan 1994 04:23:03



|>

|> >|> Hello, I am currently using Inventor (1.01) as 3D-library and I have some
|> >|> problems. First, I can write a rotation to a SoTransform-node using quaternions.Unfortunately, I can't READ rotations as quaternions. Or that's what my manual
|> >|> tells me. Is there any way to read quaternions, or do I have to translate these
|> >|> rotations to quaternions myself?
|> >
|> >I'm not sure what you mean by "read." Do you want to specify the
|> >rotations as quaternions in an Inventor file you are typing in?
|> >If so, you can't do that; in files, rotations are always specified
|> >as axis+angle. If you want to specify rotations as quaternions in
|> >a program, the SbRotation class (and the So[SM]FRotation field
|> >classes) let you do so - just pass in the 4 components of the
|> >quaternion. You can also specify rotations as axis+angle or as
|> >a rotation that brings one vector into another. You could use
|> >this program to converts a quaternion to axis+angle if you need
|> >to do that:
|> >
|> >      #include <Inventor/SbLinear.h>
|> >
|> >      main()
|> >      {
|> >          SbVec3f    axis;
|> >          float      angle;
|> >          SbRotation r(0.0, 1.0, 0.0, 0.5); // 4 components of quaternion
|> >          r.getValue(axis, angle);
|> >          printf("Axis (%g, %g, %g), angle %g\n",
|> >                 axis[0], axis[1], axis[2], angle);
|> >      }
|>
|> The problem I have is the old problem that when you read two axis+angle pairs
|> then interpolate these pairs, you lose one degree of freedom due to a singula-
|> rity in the Euler angles. In other words, if you interpolate two SbRotations
|> the resulting rotations 'look funny' in some cases. Interpolating quaternions
|> solves this problem, since quaternions were designed to eliminate just this
|> problem.
|>
|> What I want is : 1) read 4 values of SbRotation 1, then 4 values of SbRot. 2
|>               (NOT axis+angle, but 4 components of a quaternion)
|>            2) interpolate these 8 values (no problem).

I'm still not sure where you want to read these rotations from and into,
so it's hard to answer your question. If you are creating a new node
to do this, you can use an SoMFVec4f field to store the rotations as
quaternions - this field will just read and write each vector as 4
components, so it would do what you want.

|> The bad news is, I'm not going to get access to Inventor 2.0.

Why not?

|> >|> Regards,
|> >|> Ronald Kunenborg.

----

 
 
 

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Fri, 14 Jan 1994 20:41:09



Quote:>|>
>|> What I want is : 1) read 4 values of SbRotation 1, then 4 values of SbRot. 2
>|>                   (NOT axis+angle, but 4 components of a quaternion)
>|>                2) interpolate these 8 values (no problem).

>I'm still not sure where you want to read these rotations from and into,
>so it's hard to answer your question. If you are creating a new node
>to do this, you can use an SoMFVec4f field to store the rotations as
>quaternions - this field will just read and write each vector as 4
>components, so it would do what you want.

That's right - I'm going to test this in a few hours. Thanks.

Quote:>|> The bad news is, I'm not going to get access to Inventor 2.0.

>Why not?

Because I plan on graduating next month or so. And I somehow doubt this
faculty will buy an upgrade of Inventor when it's hardly ever being used.
We have our own (3D)-libs over here for most of the work that's being done -
easier to maintain, easier to understand and easier to expand.

>|> >|> Regards,
>|> >|> Ronald Kunenborg.

>----


Thanks for the help,
--
Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number             | (International Socialist)
Shake your chains to earth like dew,
which in sleep had fallen on ye
 
 
 

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Fri, 14 Jan 1994 22:23:48




>>|>
>>|> What I want is : 1) read 4 values of SbRotation 1, then 4 values of SbRot. 2
>>|>               (NOT axis+angle, but 4 components of a quaternion)
>>|>            2) interpolate these 8 values (no problem).

>>I'm still not sure where you want to read these rotations from and into,
>>so it's hard to answer your question. If you are creating a new node
>>to do this, you can use an SoMFVec4f field to store the rotations as
>>quaternions - this field will just read and write each vector as 4
>>components, so it would do what you want.

>That's right - I'm going to test this in a few hours. Thanks.

Tested it - and failed.

Well, I'll try to rephrase the problem (it may not even *be* a
problem, but just a misunderstanding of Inventor on my part).

1) I have an SoRotation. I can read the axis+angle by using
   SoRotation->getValue(&axis, &angle).

2) But what I *really* need is a quaternion, (q1,q2,q3,q4), meaning
   exactly the same as the axis+angle pair.

   (Question: are the components of the axis q1-q3 and is the angle
   just q4? I didn't think so, but now I'm starting to doubt myself)

3) Since (in inventor) I can use _s_etValue(q1,q2,q3,q4) to set
   the value of a SoRotation, there must be a way to transform
   the quaternions into an axis+angle pair (internal to Inventor).

   So I thought, maybe there's a reverse transformation hidden
   in Inventor as well, so you can just ask for the quaternion
   instead of the axis+angle.

4) If there is no such way, can anyone tell me how Inventor
   relates the quaternion to the axis+angle?

I hope this is clearer (it is for me :)). Thanks again for all
your troubles in trying to answer my vague ramblings.

Regards,
--
Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number             | (International Socialist)
Shake your chains to earth like dew,
which in sleep had fallen on ye

 
 
 

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Sat, 15 Jan 1994 00:01:55


Please ignore my previous two posts (sorry. please don't ki*aaargl* :)).

I finally found the answer my manuals didn't give me (with help from
various sources). I'm now happily implementing spherical lineair
interpolation with quaternions. Wondering how that works out.

Thanks everyone for helping me out here.

Regards,
--
Rise like lions after slumber,       | Ronald Kunenborg, The Netherlands
in unvanquishable number             | (International Socialist)
Shake your chains to earth like dew,
which in sleep had fallen on ye

 
 
 

Inventor - quaternions & collision detection

Post by Kian-Tat L » Sat, 15 Jan 1994 03:23:51


I think part of the problem here is that there are three classes that deal
with the same thing, but support different methods:

        SoRotation
        SoSFRotation
        SbRotation

It can get very confusing to determine which to use for a particular function.

I understand (I think) the design principles behind this layout, but perhaps
judicious use of multiple inheritance would allow a more consistent appearance
for these and similar classes.

--

Materials & Molecular Simulation Center, Caltech
Henry Spencer left-of-| signature fan

 
 
 

Inventor - quaternions & collision detection

Post by hei.. » Sat, 15 Jan 1994 03:37:20


This is a piece of C code I use in an animation program to get from
axis + angle to Euler parameters (quaternion).

        sa[0] = angle (radians)
        sa[1] = X component of axis \
        sa[2] = Y component of axis  > unit length vector
        sa[3] = Z component of axis /

        float   q[4], s, sa[4];

        s  = (float)sin((double)(0.5*sa[0]));
        q[0] = (float)cos((double)(0.5*sa[0]));
        q[1] = sa[1]*s;
        q[2] = sa[2]*s;
        q[3] = sa[3]*s;

It seems from Ronald Kunenborg's  posting that his q4 is my q[0].

Harry Heinen


TNO Road-Vehicles Research Institute            Phone  : +31 15 697430
P.O.Box 6033, 2600 JA Delft, The Netherlands    Fax    : +31 15 624321

 
 
 

Inventor - quaternions & collision detection

Post by Gavin Be » Sat, 15 Jan 1994 03:54:34


Quote:>1) I have an SoRotation. I can read the axis+angle by using
>   SoRotation->getValue(&axis, &angle).

>2) But what I *really* need is a quaternion, (q1,q2,q3,q4), meaning
>   exactly the same as the axis+angle pair.
>   (Question: are the components of the axis q1-q3 and is the angle
>   just q4? I didn't think so, but now I'm starting to doubt myself)

Use:
void
SbRotation::getValue(float &q0, float &q1, float &q2, float &q3) const

Quote:>3) Since (in inventor) I can use _s_etValue(q1,q2,q3,q4) to set
>   the value of a SoRotation, there must be a way to transform
>   the quaternions into an axis+angle pair (internal to Inventor).

Sure, just set the SbRotation as an axis/angle and then get it as a
quaternion.

Quote:>   So I thought, maybe there's a reverse transformation hidden
>   in Inventor as well, so you can just ask for the quaternion
>   instead of the axis+angle.

See above.

Quote:>4) If there is no such way, can anyone tell me how Inventor
>   relates the quaternion to the axis+angle?

Sure, here's some source that should make it clear:
(note that SbRotations store rotations as quaternions internally in a
private quat[4] array)

////////////////////////////////////////////////////////////////////////
//
// Description:
//    Sets value of rotation from 3D rotation axis vector and angle in
//    radians.
//
// Use: public

SbRotation &
SbRotation::setValue(const SbVec3f &axis, float radians)
//
////////////////////////////////////////////////////////////////////////
{
    SbVec3f     q;

    q = axis;
    q.normalize();

    q *= sinf(radians / 2.0);

    quat[0] = q[0];
    quat[1] = q[1];
    quat[2] = q[2];

    quat[3] = cosf(radians / 2.0);

    return(*this);

Quote:}

--

 
 
 

Inventor - quaternions & collision detection

Post by Ronald Kunenbo » Sat, 15 Jan 1994 19:11:24


The problem has been solved (thanks everyone, for all the hints & solutions).
It turned out to be easier than expected:

1) The SoSFRotation is actually an SbRotation. Took me a while to figure this
   out. But at least this could be found in the manual.

2) Any SbRotation can be considered to be a quaternion, and functions to
   get the value as both axis+angle & quaternion are available.

3) Finally, the problem I needed the quaternions for (weird interpolation-
   results) was solved when I looked into the SbLinear.h-file. Apparently,
   a function "slerp" has already been defined (Spherical LinEaR
   interPolation?). This interpolation takes into account
   the fact that you are interpolating on the surface of a (hyper?)sphere,
   and therefore cannot do a direct linear interpolation of the quaternions.
   Such a direct interpolation would result in a "cut off" *through* the sphere,
   instead of a straight path across the surface.

The final code is:
interpolated rotation (SoSFRotation) = slerp( startSoSFRotation.getValue(),
                                              endSoSFRotation.getValue(),
                                              fraction [between 0 and 1]);

where SoSFRotation.getValue() gives a pointer to the contents of an SbRotation
as result.

Once again thanks to everyone who helped put me on the right track.

Regards,
--

Rise like lions after slumber, in unvanquishable number
Shake your chains to earth like dew, which in sleep had fallen on ye,
Ye are many, they are few.           - Shelley, `The Mask of Anarchy' (1819)