I have a 3d camera in a 3d world where I have ability to rotate a point about an arbitrary line. So I guess I want to give the camera a default center position of 0,0,0, then an x-axis-point at 1,0,0, a y-axis-point at 0,1,0 and a z-axis-point at 0,0,1. Now whenever i do any rotation of the camera, all 3 points should rotate, thus the camera can rotate around axises relative to itself (like say it is already tilted down 90 degrees, now turning to the right 180 degrees should end up tilted *up* 90 degrees (so it rotates about it's own axises instead of the "hard coded" fixed normal x/y/z axises.
Ok, first of all, you shouldn't rotate from a rotation (otherwise slight rotation errors amplify to not be precise), so that original center/xAxisP/yAxisP/zAxisP needs to stay unmodified, then any time u want to rotate, copy that original template and apply the desired rotations. Like probably the x axis angle would be 0-359 degrees, same for y and z axis.
So if I think about this thing in my mind it's obvious and works. Like start at the default, pitch forward, ok now I'm forward, turn right (relative to the previous pitch forward), do this next, then that, it mentally works. BUT it seems almost like you need a neverending list of an order of which axises you turned on, and when, especially since you need to start at the default each time to neutralize accumulated rotation imprecision. FIRST i pitched forward, THEN i turned right, THEN... This list would eventually be infinity long to be accurate.
Ok, well maybe I only need 3 angle numbers: yAxisAngle(turning),xAxisAngle(pitching), zAxisAngle(rolling). And say my code is set up so it always does only those 3 rotations in that order, starting from default. Each angle starts at zero. So say I roll right first. That was the first move and other angles are zero so it'd be:
no y change, no x change, z roll right (screen would be tilted right)
NOW I do a pitch down:
no y change, x pitch down, z roll right (screen would be tilted right)
The code rigidly does them in that order even though I sequentially did them in a different order, so I'm pretty sure it'd mess it up but even moving my hand as a 3d object in front of my face it's hard to tell.
Anyway, I think starting at the default and going from there is the wrench in the system complicating it. I thought of a solution while writing this maybe. Instead of rotating, maybe I'll just use a point.setFrom(otherpoint,angle(s),distance) function. That way the distances will stay exact without accumulated rotation imperfection (and I won't have to keep a default to start from each time, just modify the current data itself when rotating).
the standard order I always used was heading/pitch/roll, from airplane perspective. I think most things use this ordering.
for order of operations, rotate first, then translate, in 3-d graphics. You also tend to have more degrees of freedom. You should have 3 angles of rotation and 3 axis of translation. HPR only covers the angles, but not the translation. I think you knew this.
also be mindful of whether you need quaternions. If you go straight up, rotate spin, then rotate left/right, then move, it hits a numerical anomaly. If you need to support that, you need 4d space mapping to counter the problem and retain the components to get the correct directions.
Yes, I believe you'll need quaternions to do proper yaw-pitch-roll. Axis rotations are best when you want to do absolute rotations and don't care about losing a degree of freedom at extreme angles. For example, they're great to code cameras in FPS games.
Cool, I'll look up quaternions, don't remember hearing of those before.
Anyway I finished the attempt at rigidly starting from the default then do the 3 in order: turn,pitch,roll. with a cube in front of me (in python). what happened was sorta like being in a spaceship you roll first so cube rotates into a sideways diamond. Now you try to pitch down, which should simply make the diamond move up (as if in a spaceship pitching down now after the roll). instead what happened was the diamond moved diagonal up/left (who knows though, maybe cuz I coded something screwy, but I suspect because yaw/pitch/roll order).
However it seemed to work if you turn,pitch, then roll or pitch,turn, then roll (roll last).
I'll look up quaternions or maybe try not resetting it to (1,0,0)(0,1,0)(0,0,1) each time.
I "untranslated" 3d points from the camera position, then "unrotated" them from the camera rotations in reverse order (roll,turn,pitch instead) since I was "un" rotating them then did a 2d projection w/ similar triangles to find screen x/y.
Actually I don't know if I'm susceptible to "gimbal lock" because when I rotate the camera to pitch down (about x axis), I *also* rotate the camera's z and y axis so all camera axises stay in a permanent 3d right angle wherever the camera rotates. Seems different than animations of nested gimbal rings because those are attached to eachother and affect eachother or something, but I could be wrong.
I think if you fudge to skip the anomaly (just insert if blah == 0 then blah = 0.3 or something where blah is in degrees (or figure out a suitable rad constant). Somewhere around 1/2 or 1/3 of a degree or so the values are suitable for storage in a double with only minor roundoff problems etc.
I am less sure of what you are doing, but I will reiterate that rotating in place first, then moving is correct if the goal is to update the xyzhpr of an object such that it is at a new location pointed in a new direction (eg, your camera is the view from a vehicle being driven in a normal fashion like an airplane). Rotating about a point (or line or plane etc) is not the same thing (eg, your camera is a planet in orbit). Rotation about something, you don't translate directly, you update xyz and hpr from the rotation matrix. Two completely different things. (Just in case I confused you).
the orientation of the thing is xyzhpr. and it has its own coordinate system (lines through the center of the object) Rotation about something uses the global coordinate system, and you have to back out the xyzhpr from that to update it (if you need/use it at all).