[ODE] quat to eulerXYZ
Patrick Enoch
Hendrix_ at gmx.net
Sun Jun 26 03:20:51 MST 2005
these conversions work (for your physics engine maybe):
void eulerYXZfromquat( DCoordinate *euler, quat _quat )
{
quat quat = _quat;
double maginv = 1.0/SQRT( SQR(quat.r)+SQR(quat.x)+SQR(quat.y)+SQR
(quat.z) );
quat.r *= maginv;
quat.x *= maginv;
quat.y *= maginv;
quat.z *= maginv;
double asinarg = 2*(quat.y*quat.z + quat.r*quat.x);
if (asinarg<-1)
asinarg=-1;
if (asinarg>1)
asinarg=1;
euler->x = asin( asinarg ) *EULER_SCALE_INV;
euler->y = atan2(-2*(quat.x*quat.z - quat.r*quat.y),
quat.r*quat.r - quat.x*quat.x - quat.y*quat.y +
quat.z*quat.z ) *EULER_SCALE_INV;
euler->z = atan2(-2*(quat.x*quat.y - quat.r*quat.z),
quat.r*quat.r - quat.x*quat.x + quat.y*quat.y -
quat.z*quat.z ) *EULER_SCALE_INV;
};
void eulerZXYfromquat( DCoordinate *euler, quat _quat )
{
quat quat = _quat;
double maginv = 1.0/SQRT( SQR(quat.r)+SQR(quat.x)+SQR(quat.y)+SQR
(quat.z) );
quat.r *= maginv;
quat.x *= maginv;
quat.y *= maginv;
quat.z *= maginv;
double asinarg = -2*(quat.y*quat.z - quat.r*quat.x);
if (asinarg<-1)
asinarg=-1;
if (asinarg>1)
asinarg=1;
euler->x = asin( asinarg ) *EULER_SCALE_INV;
euler->y = atan2( 2*(quat.x*quat.z + quat.r*quat.y),
quat.r*quat.r - quat.x*quat.x -
quat.y*quat.y + quat.z*quat.z ) *EULER_SCALE_INV;
euler->z = atan2( 2*(quat.x*quat.y + quat.r*quat.z),
quat.r*quat.r - quat.x*quat.x + quat.y*quat.y -
quat.z*quat.z ) *EULER_SCALE_INV;
};
void eulerXYZfromquat( DCoordinate *euler, quat _quat )
{
quat quat = _quat;
double maginv = 1.0/SQRT( SQR(quat.r)+SQR(quat.x)+SQR(quat.y)+SQR
(quat.z) );
quat.r *= maginv;
quat.x *= maginv;
quat.y *= maginv;
quat.z *= maginv;
euler->x = atan2( 2*(quat.y*quat.z + quat.r*quat.x),
quat.r*quat.r - quat.x*quat.x - quat.y*quat.y +
quat.z*quat.z );// *EULER_SCALE_INV;
double asinarg = -2*(quat.x*quat.z - quat.r*quat.y);
if (asinarg<-1)
asinarg=-1;
if (asinarg>1)
asinarg=1;
euler->y = asin( asinarg );// *EULER_SCALE_INV;
euler->z = atan2( 2*(quat.x*quat.y + quat.r*quat.z),
quat.r*quat.r + quat.x*quat.x - quat.y*quat.y -
quat.z*quat.z );// *EULER_SCALE_INV;
};
void quatfromeulerZXY( quat *quat, DCoordinate euler )
{
const double cx(cos(0.5*euler.x*EULER_SCALE));
const double cy(cos(0.5*euler.y*EULER_SCALE));
const double cz(cos(0.5*euler.z*EULER_SCALE));
const double sx(sin(0.5*euler.x*EULER_SCALE));
const double sy(sin(0.5*euler.y*EULER_SCALE));
const double sz(sin(0.5*euler.z*EULER_SCALE));
quat->r = cx*cy*cz + sx*sy*sz;
quat->x = sx*cy*cz + cx*sy*sz;
quat->y = cx*sy*cz - sx*cy*sz;
quat->z = cx*cy*sz - sx*sy*cz;
double maginv = 1.0/SQRT( SQR(quat->r)+SQR(quat->x)+SQR(quat->y)
+SQR(quat->z) );
quat->r *= maginv;
quat->x *= maginv;
quat->y *= maginv;
quat->z *= maginv;
};
Patrick
On 26. Jun 2005, at 2:36 Uhr, cr88192 wrote:
>
> ----- Original Message ----- From: "Patrick Enoch" <Hendrix_ at gmx.net>
> To: <ode at q12.org>
> Sent: Sunday, June 26, 2005 1:04 AM
> Subject: [ODE] quat to eulerXYZ
>
>
>
>> Hello all,
>>
>>
>> I am having problems with angular velocities. currently i am
>> interfacing ODE to another program which uses eulerZXY.
>> so if i have a body with eulerZXY angular velocity, I need to
>> convert it to ODEs eulerXYZ.
>> i am using quaternions as the interface, which looks like this:
>>
>> prog eulerZXY at time A and B -> quats at time A and B -> ODE
>> eulerXYZ at time A and B
>> (angular velocity is difference between eulers divided by (B-A))
>>
>> BUT:
>> when converting quats -> eulerZXY there are jumps in the
>> conversion. for example:
>>
>> euler ZXY (0,89,0) -> eulerXYZ (89,0,0) (works fine)
>> euler ZXY (0,91,0) -> eulerXYZ (180,-91,180) (pretty far away
>> from the above)
>> (values as far as i remember. but i think the prob is clear. the
>> difference should be small, but the resulting
>> angular velocity is very big. conversion depends on into which
>> quadrant the rotation points, its an
>> unsteady function. )
>>
>> anyone knows a quat -> euler converter, which i can tell to give
>> me values "near" to another triple?
>>
>>
> your case looks ugly...
>
> but, yeah, I feel doubtful ode is using euler angles for angular
> velocity, much more likely it is a "spin vector" (or whatever they
> are called, I don't really know).
>
> conversion may be problematic, but I doubt it is "impossible".
>
> one thing that could be possible (just off the top of my head):
> converting to quats (I guess you were allready doing this);
> transforming a point (either directly, or via a matrix);
> "undoing" the rotation.
>
> also possible would be, if using a matrix, to just grab the point
> as one of the matrix's unit axis, then the same approach as below.
>
> "undoing" would consist of measuring the angle for each axis (eg:
> via atan2 or such), and then counter rotating the axis for the angle.
> in the case of ZXY, the undo would probably be done in YXZ order.
>
> actually, a single point may not be sufficient, more likely it
> would involve trying to counter-rotate the whole matrix, at each
> step trying to re-align the matrix. ideally, at the final step the
> matrix would have been rotated back to identity. it may be
> necessary to try to determine what axis to try to align, eg,
> because one or the other might lie near/at the origin wrt a 2D plane.
>
>
> herin lies another problem with eular angles, given the nature of
> the angles themselves, there will tend to be abrupt jumps, a
> converter for angular velocity could maybe try to determine the
> direction for each axis, and flip it depending on sign or such.
>
> if(w[i]<0)a[i]=360-a[i]; //maybe?
>
> another problem is magnitude, what if the velocity is fairly fast,
> this could generate an arbitrary spin?
>
> a thought that comes up is first normalizing the magnitude, so the
> resultant angles basically tell where it was spinning, but not how
> much. this magnitude could then be multiplied into the resultant
> angles.
>
>
> as noted by someone else, maybe it would also be possible to just
> set up a transformation matrix and directly transform the velocity
> to angles?
> I don't know really, my mind has a little difficulty processing the
> relationship between the representations (in some cases, the
> generated point is likely to be the same, in some, no...).
>
> problably, yeah, stupid euler angles and their stupid ordering, and
> their stupid singularities...
>
>
> all this could work, it is just a thought though.
>
> ok, I am now sort of doing my own physics api (doubtful it will be
> able to really compare with ode, I guess probably more for personal
> experience or something...).
> at one point I had tried converting the internal quats to eular
> angles for the front end interface, but dropped this as it felt
> like a bad idea (and apparently the transform doesn't work really,
> but it was much more naive than the one above).
>
> later decree: all angles will be quats and all velocities/torques
> will be spin vectors. if a frontend wants euler angles that is
> another problem...
> also, jerkoff: removing, partly re-adding, and now once again
> basing things on solid-types (also just showing the quick
> succession of rewrites). for their annoyance, solidtypes are just
> too useful it seems (better than trying to magically come up with
> collision/contact info for unknown types...).
>
> I am going for a very opaque api, it is difficult to know how much
> to expose (eg: whether or not it is safe to expose the internal
> math functions, for example). a lot of the math is being done with
> macros and inlines, and is currently not exposed to the "external"
> headers.
>
> me half-thinking: the api should hide the implementation wherever
> possible.
>
> if I wanted to switch over to using ode as the backend, for
> example, the api/frontend shouldn't notice much. as an example: the
> backend code is currently based primarily on doubles, the frontend
> api provides both float and double based calls.
>
> some details are necissarily exposed though, eg, at present things
> like the intergrator steps and whatever can be get/set as "world
> attributes".
> quite probably, it is not possible to sufficiently generalize the
> said api.
>
> in my case, then, it is all just a more personal fiddly project.
>
> but whatever on this...
>
>
More information about the ODE
mailing list