been stuck for about a month on this -
i use "euler angles" (tait-bryan angles) to describe rotation coordinates.
as far as i understand (i would like to be wrong), in order to concatenate two 2d rotations, eg. to rotate around an arbitrary orientation, it is necessary to convert the angles to a matrix, perform the rotations, then convert back to euler.
i have thoroughly failed at this.
i think my stumbling block is that i set out to use a LH/LH coordinate/rotation system (being familiar with LH/LH from years of POVray use). my initial attempts were.. terrible beyond description.. eventually i adopted someone else's LH/RH system and achieved some modicum of performance.
i think it must be that the conversion formulas i've been given must suck, i've tried this so many times. the best performance will perform well for initial simple rotations, then start to develop an inaccuracy which switches back and forth between two wrong places.
i cannot identify what it is about my implementation that does not work, since i have followed the conversions to a tee (both from geometrictools.com and euclideanspace.com).
i do not think it is my matrix implementation, while i've never needed one before it's not that complex and it has been doublechecked and ok'ed by someone else.
i can't post meaningful screenshots of the error, because it is bilocating between two places, so taking a screenshot would only show one of the locations.
my source is here, if anyone is intrepid enough - the matrix implementation is at the end of vectoralg.h and the "game loop" is in game.h. all it does is draw a tetrahedron on the screen which is rotated by the arrow keys.
http://xoxos.net/temp/source.zip
the matrix is arranged
abc
def
ghi
and read from the angles like this:
1 2 3 4 5 6 7 8 9
|
paramxc = cos(param.x); paramxs = sin(param.x);
paramyc = cos(param.y); paramys = sin(param.y);
paramzc = cos(param.z); paramzs = sin(param.z);
g = paramys * paramzc;
h = paramys * paramzs;
a = paramyc * paramzc; b = paramyc * -paramzs; c = paramys;
d = paramxs * g + paramxc * paramzs; e = -paramxs * h + paramxc * paramzc; f = -paramxs * paramyc;
g = -paramxc * g + paramxs * paramzs; h = paramxc * h + paramxs * paramzc; i = paramxc * paramyc;
|
the matrix is converted back to radians here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
if (c < .99999f) {
if (c > -.99999f) {
param.x = atan2(-f, i);
param.y = asin(c);
param.z = atan2(-b, a);
}
else {
param.x = -atan2(d, e);
param.y = -pih;
param.z = 0.f;
}
}
else {
param.x = atan2(d, e);
param.y = pih;
param.z = 0.f;
}
|
if you use the app you can see the problem - obviously the error is in the matrix-to-euler conversion, but this step is where i have to trust my source...
if some brilliant person can discern the problem, please tell me! otherwise, is there a left handed system *anywhere* that i can really trust? or do i have to go and get nasa's right handed system?
this problem is just lousy.