Archived

This topic is now archived and is closed to further replies.

Bucket_Head

3D Movement Math; Trig City

Recommended Posts

Hey everybody! I am making a fun little OpenGL flight simulator, and it is going quite nicely so far. My problem now relates to movement in 3D. As we all know, if you''re pointing straight down one axis and go forward, your position will change by the distance value, and that when you''re pointing at some obscure angle you should go the same distance, but in different amounts for each of the delta_x, delta_y, and delta_z values. Initially I started working in 2-Dimensional movement, with a ship (ahem, flying triangle) that didn''t ever change its roll or pitch values, but where its yaw was always incrementing (meaning it would keep going in a circle on the x-y plane (I am having z be the "up" value for this, and having y be north/south and x be east/west)). The initial formula I used was this: x_move = (float)(sin(yaw) * dist); y_move = (float)(cos(yaw) * dist); ...The astute amongst you may realize, after flipping out your calculator, that things seem a little upside down and backwards. Well, Instead of using traditional math style of trigonometry, where it starts pointing down the x axis and increments counter-clockwise, I opted to use it where it starts pointing up the y axis and increments clockwise. I think it makes a lot more sense that way, and I don''t know why they didn''t ever do it that way for math. When you think about sin and cos in terms of their values, the idea of changing their orientation doesn''t really matter; they still work just as much. Anyway, as you can see, I am only affecting the x and y values and only working with the yaw. In the end, I need to work with roll, pitch, and yaw to find x, y, and z values. After looking at that and thinking about how the initial pitch value is 0, and how the cos of 0 is 1, I deduced the following formula (which works): x_move = (float)(sin(yaw) * cos(pitch) * dist); y_move = (float)(cos(yaw) * cos(pitch) * dist); z_move = -(float)(sin(pitch) * dist); ...As you can see, I am accounting for yaw and pitch, and finding x, y, and z values. This works great, the only problem is that it''s not working with roll. I am not quite sure how to go about this one, since when you change the roll it tilts everything...Hmm... Oh, and the reason I have the - in front of z_move...well, left without the -, things move the opposite as they should *shrugs* so I just put the - there...Is that not a good idea? Anyways, I would really appreciate any help anyone could give on this. Once I have roll working, I will have complete true 3D movement on all 3 axes and all 3 angles of rotation. Once I have this in hand, I can go on with all sorts of funky flight yippy - very enjoyable times are to had by all. Thank you for your time. - Hai, watashi no chichi no kuruma ga oishii deshita! ...or, in other words, "Yes, my dad's car was deliscious!"

Share this post


Link to post
Share on other sites
Bear with me as this is critical for you to understand how to handle 3D orientations. You really need to stop thinking in terms of Euler angles (yaw, pitch, roll) when you want to do full 3D movement of a spaceship. It works fine with something like a Quake viewpoint when you only usually Yaw, sometimes pitch, and seldom if ever roll.

However, in a flight sim this will be a real problem for you. Assume your order of rotations is Yaw, Pitch, Roll. In my notation (somewhat standard for CG but different for most math people) that is Y, X, Z rotations. Now say your ship is in some arbitary orientation like (10, 0, 90). Visualize that orientation with your hand. Now say the player pulls back on the stick at this time. The expected behavior would be that the pitch increases by 45 degrees or something. Try that with your hand and see where you are pointing.

However, you can''t just add 45 to the pitch. That would give you (10, 45, 90). Again use your hands and see why that is wrong. Since the roll is 90, the 45 should be added to the yaw.

A much easier approach is to use a better 3D orientation rep (o-rep) then Euler angles. You will see lots of people talk of matrices or quaternions. It doesn''t really matter what you use but that it allows you to combine rotations easily. What you will do is take your initial orientation (0,0,0) and convert that to your o-rep. This is easy and any basic 3D book or article will cover that.

Now when you want to turn, you take how you want to turn, say (0, 45, 0) and convert it to your o-rep. Combine this with your current orientation (usually matrix or quaternion multiply) and away you go.

Matrices have a nice property that will be useful for your ship. You can directly extract the forward direction vector at any time. Very useful for moving ahead so I would recommend that o-rep but up to you.

Now wasn''t that better than a simple answer like "Use Matrices, dude..."

-Jeff

Share this post


Link to post
Share on other sites