#converting quaternion to euler angles
81 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.
I expect quaternionToEulerRot to give me -70.f, 125.f
I heavily based my formulas on this article: https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles, had to change some stuff around to get the expected result for eulerRotToQuaternion but applying the changes to the reverse formula is just not making sense to me
converting quaternion to euler angles
your y and z (and their signs) are flipped in line 40-41
additionally, on line 57 the x/z and w/y should also be switched
line 40/41:
(cx * sy * cz) - (sx * cy * sz), // quat.y
(sx * cy * cz) + (cx * sy * sz) // quat.z
line 57:
float sinp = 2.f * (quat.x * quat.z - quat.w * quat.y);
btw, (after the 40/41 fix) your w and x are swapped compared to wikipedia and likewise for z and y
this is why they need to be switched for line 57 (the other ones are all addition)
@rapid swallow
I actually intentionally switched some stuff around for eulerRotToQuaternion, and that formula produces expected results
i think my target has roll and pitch flipped or something
or something flipped not sure, but i just know that eulerRotToQuaternion is "correct"*
oh ok, then i guess you just need to switch quat.y and quat.z in your quaternionToEulerRot and flip the signs for both
But, as I said above, eulerRotToQuaternion gives me correct numbers
dont really know why but it does lol
huh...
the relationship is really close as you can see
swap the members and take their complement or something...but thats cheeky
wait you mean the r1 numbers? or the q2?
r1 is what im starting with
in my console i expect to be able to convert r1 to a quat then back to a vec2 and end up with the same values that i started with
well these 2 changes fix r1
(the second one fixes sign of first number, and the first one fixes the 55/110 to 70/125)
oh um....
it seems that rot.x has to be within (-90, 90)
probably because of the asin
I applied your requested changes here
it just so happens that those are the bounds of my rot
its for a player
if they look straight up, they are at -89.99 degrees
straight down, 89.99
should i be concerned with that?
uh gimme 1 sec
so the player's head x rot is in a range of (-90, 90), head y rot is (-180, 180)
current code fwiw
gah i hate floating points
would it be possible to switch out the float for doubles?
sometimes it just likes to break on me and i don't exactly know why
sure
I mean, my target wants floats but its the same dif
are you getting floats as inputs as well?
yes
mm ok
the quat is just gonna be like that vec4 thing with 4 floats
it would probably be better if you used doubles for the processing stuffs, to minimize error
yes, I see
i'm getting some pretty large errors here lmao :\ (>0.05)
just by virtue of floating point inaccuracies?
i should prob know this lol but do the errors "build up" over time?
i think the errors happen more toward the extremes
like, would i benefit if i were to do everything in terms of doubles then cast the final result to a float?
probably... but i can check
I can't change the actual inputs and outputs to doubles because im working with someone elses api
understandable
a lot of graphics stuff is done in float becuse i think even modern gpus sometimes don't support double lol
i can't tell if it's better or the same lmao
i'm getting 89.9984, -166.899 -> 90, -166.854
89.9802, -169.836 with float (the first one was double as intermediary)
i guess only way to tell is if you actually test a double input and output then compare that
seems like a negligible difference to me
i suppose so
but in practice i should keep in mind how lots of repeated arithmetic might have noticeable precision errors with floats
here is a random "fuzz" thing i hacked together (it is not very good code)
Vec2 r2;
for (float i = -89.9f; i < 90.0f; i += 0.1f)
{
for (float j = -179.9f; j < 180.0f; j += 0.1f)
{
r2.x = i;
r2.y = j;
auto q2 = eulerRotToQuaternion(r2);
auto r1 = quaternionToEulerRot(q2);
if (std::abs(r1.x - r2.x) >= 0.1 || std::abs(r1.y - r2.y) >= 0.1)
{
std::cout << i << " " << j << std::endl <<
r1.x << " " << r2.x << "\t" << r1.y << " " << r2.y << std::endl;
}
}
}
i unfortunately have to leave, but you can play around with the things and see if the errors are acceptable
or whatever, idk
@rapid swallow Has your question been resolved? If so, run !solved :)