views:

319

answers:

5

I hope this is the proper location to ask this question which is the same as this one, but expressed as pure math instead of graphically (at least I hope I translated the problem to math correctly).

Considering:

  • two vectors that are orthogonal: Up (ux, uy, uz) and Look (lx, ly, lz)
  • a plane P which is perpendicular to Look (hence including Up)
  • Y1 which is the projection of Y (vertical axis) along Look onto P

Question: what is the value of the angle between Y1 and Up?

As mathematicians will agree, this is a very basic question, but I've been scratching my head for at least two weeks without being able to visualize how to project Y onto P... maybe now too old for finding solutions to school exercises.

I'm looking for the trigonometric solution, not a solution using a matrix. Thanks.

Edit: I found that I needed to determine the sign of the angle, relative to a rotation axis which had to be Look. I posted the final code on my linked question (see link above). Thanks to those who helped. I appreciate your time.

A: 

You need to know about vectors in 3D space. I think that a fundamental understanding of those, especially dot and cross products, will sort you out. Seek out an elementary vectors textbook.

two vectors that are orthogonal: Up (ux, uy, uz) and Look (lx, ly, lz)

Orthogonal vectors have a zero dot product.

a plane P which is perpendicular to Look (hence including Up)

If you take the cross product of Look into Up, you'll get the third vector that, along with Up, defines the plane perpendicular to Look.

Y1 which is the projection of Y (vertical axis) along Look onto P

I don't know what you're getting at here, but the dot product of any vector with Look gives you the magnitude of its component in the Look direction.

duffymo
Thanks, I know about them, at least I know what they are. I also know what is a quaternion or a matrix. But I still don't know how to solve this trigonometric problem. Do you?
742
Yes, I do. I find it hard to believe that somebody who claims to know quaternions and matricies can't solve a problem like this. Doesn't sound right to me.
duffymo
Everybody can read a book on 3D Math, or Martin Baker's nice pages, I have done all, and the day after throw smart words like orthogonality, cross-product or talk about around, but that don't mean knowing how to solve a problem. I don't see what is hard to believe.
742
A: 

This is a relatively simple problem using vector math. Use the equation for vector projection to get Y1, then the trigonometric equation for the dot product to get the angle between Y1 and Up.

This equations would be pretty easy to implement yourself in just about any language, but if you're asking this sort of question you may be intending to do more heavy-duty vector math, in which case I'd suggest trying to find a third-party library.

tlayton
Thanks. I'm ok with the two steps you suggest. I'm using WPF, and Vector3D has a AngleBetween method, so pretty simple for this operation. The problem is only the value of Y1 that I can't compute. If I had to project along one of the X,Z axis I'd know how to do, but not along Look. Can't you help me by providing the formula for Y1x, Y1y and Y1z? I've been told this is basic math, but so far nobody provided the magic formulas. So if you know, I'd appreciate and grant you the answer to the two questions.
742
+2  A: 

I'm just doing this on paper. I hope it's right.

Let's assume Up and Look are normalized, that is, length 1. Let's say that plane P contains the origin, and L is its normal. Y is (0, 1, 0)

To project Y onto P, find its distance to P...

d = Y dot L = ly

...and then scale the normal by -d to get the Y1 (that is, the projection of Y on P)

Y1 = (lx * ly, ly * ly, lz * ly)

Now normalize Y1, that is, scale it by (1 / length). If its length was 0 then you're out of luck.

The dot product of Y1 and Up = the cosine of the angle. So

angle = acos(Y1 dot Up)
Detmar
Detmar, Thanks. That's exactly the answer I was looking for. Tom has improved your answer, but I'll mark yours as good in priority, because you answered first. I hope it will be possible to rank Tom's as well. Please see my comment to Tom about the validity of the solution. Thanks a lot. Is there a page I can consult to learn a bit and improve my knowledge about this specific solution?
742
+1  A: 
  • two vectors that are orthogonal: Up (ux, uy, uz) and Look (lx, ly, lz)
  • a plane P which is perpendicular to Look (hence including Up)
  • Y1 which is the projection of Y (vertical axis) along Look onto P

I'll assume Up and Look are unit vectors. Let Y=(0,1,0).
Let's find Y1.

Y1 = Y - (Y*Look) * Look Y1 = Y - ly * Look Y1 = ( -ly*lx, 1 - ly*ly, -ly*lz )

Note that Y1 will be (0,0,0) when Look is (0,1,0) or (0,-1,0).

Like Detmar said, find the angle between Y1 and Up by normalizing Y1 and finding the arccos of Y1*Up (where * is dot product)

Tom Sirgedas
Tom, thanks a lot. I marked Detmar as the good answer in priority, but you improved it, just post your answer to my linked question, I will mark you as the correct answer here, to give you guys both points. The solution has improved my application. I can turn objects and the bank angle is correctly made null twice a turn. Very good. During a 360° heading turn, there is still 180° with the wrong bank. I'll keep you posted of what I'll do to correct. No easy for me to tell since there are also handedness changes involved, that's a lot complex for me ;-)
742
Note that our formulas for Y1 are slightly different. Make sure to try both!
Tom Sirgedas
I use yours since the (1-ly*ly) is better in my case. I found that my residual problem was because when I measure the angle between Y1 and Up, this angle is always positive (which is logical without the reference to a rotation axis), while I needed a signed angle. So I added a test based on Look, Up and Y1. And that's now ok. I'm relieved of a great great pain actually, thanks to you friends! I posted the code used on my linked question.
742
A: 

If Y = (0,1,0) Then

Y1 = (-ly*lx, 1 - ly*ly, -ly*lz)

|Y1| = sqrt(Y1x^2 + Y1y^2 + Y1z^2)

|Up| = sqrt(Upx^2 + Upy^2 + Upz^2)

Bank Angle = (Y1x*Upx + Y1y*Upy + Y1z*Upz)/(|Y1|*|Up|)

Lance Roberts