Jump to content
  • Advertisement
Sign in to follow this  

Vector3D - Get the Compass orientation ?

This topic is 2608 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone !

I am looking to find a way to get the Compass orientation of a 3D Vector object. I need a result in degrees from 0 to 360.
The way i could know the orientation of the object.

Here is what i did so far, but it does not seem to work.
I can't understand why..

var objectForwardVector : Vector3 = object.transform.forward;
var worldForwardVector : Vector3 = object.transform.forward;
objectForwardVector.x = 0;
var dotProduct : float = (objectForwardVector, worldForwardVector);
return Acos( dotProduct ) /Math.Pi * 180;

Right now, the Compass value change when i move my object on the Longitudinal Axis. (whatever the Longitudinal axis, the Compass orientation should be the same).

anyway, it look strange..

Any idea on that ?
Thank you in advance for any help !


*'Edit'* changed int to float..

Share this post

Link to post
Share on other sites
A couple of things I noticed:

1. If transform.forward returns a unit-length vector, you don't need to normalize worldForwardVector.

2. 'dotProduct' should probably be of a floating-point type rather than an integer.

3. Strictly speaking, you should generally clamp the argument to acos() to the range [-1, 1] to correct for any numerical error.

I'm not sure why .x is being zeroed out or what angle it is exactly that you're measuring, but the first thing I'd try is making 'dotProduct' a float rather than an int, and see if that helps.

Share this post

Link to post
Share on other sites
The arc-cosine of the dot product can only give you an angle from 0 to 180 degrees. What you want to use is atan2(y,x), ignoring the z coordinate (or whatever coordinate is up).

Share this post

Link to post
Share on other sites
The method shown in the OP cannot work because in
a . b = |a| * |b| * cos( <a,b> )
the term <a,b> means the angle between directions a and b (and not "from a to b"). As such the result must be in [0°,180°] what contradicts the requirement mentioned in the OP. (EDIT: as alvaro has already pointed out during I wrote this.)

Maybe to yield a compass direction the OP wants to map the 3D direction from the reference point to the target point onto a plane, and to measure the angle from a reference direction on the plane to the mapped direction. (That is more or less how a compass works, where the horizontal part of the magnetic vector field is compared to the north arrow on the compass body.) I think that is the reason why the x component is set to 0. But why those dot-product is computed? I have no clue ...

IMHO, with the local-to-global transformation of the reference plane, using e.g. x-z as the plane and its z axis as north arrow, and the position vector of to the target point, the computation of the compass direction may be:
1. Computing the difference vector from the plane's origin (where the compass is located) to the target point; perhaps normalize it.
2. Transform the difference vector into the plane's local space.
3. Use the atan2(...) function with the x and z components to compute the angle, perhaps with a 90° correction if needed.

Share this post

Link to post
Share on other sites
Hi all and thank you very much for taking the time to answer.

I would like to clear some points : (Please forgive my English)

jyk in the code i wrote : var dotProduct : int i just wrote it by heart, but my original code was a float. var dotProduct : float.
So sorry for that mistake !

the wrold X vector was set to 0 to indicate the starting angle (North).
Also, i think that getting values from 0 to 180 are not hard to convert to 360. because, if i go in the North, my Object forward vector would be 0, 0, 1
And if i go to the south it will be 0, 0, -1, so i can say something like, if the result is positive, calculate the first 180 half, and if the result is negative, calculate the other 180 half. In order to get my full 360 circle.

Anyway, alvaro i will try with atan2 !
In the engine i am using (Unity) the up vector is y.

haegarr Thank you for writing this, it will help me to understand ! (It is sill hard for be because English is not my first language, so if you add Math on top of that hehe)..

So basically a normalized compass pointing in the North direction should be (0, 0, 1) right ?
Anyway, i will try this tonight and report as soon as possible here.

Thanks again !

Share this post

Link to post
Share on other sites
Thanks you so much guys.
After some test in my engine, it looks like it is working perfectly.

Here is my final code :

public function getCompass():Number {
var result : float = Mathf.Atan2(transform.forward.x,transform.forward.z) / Mathf.PI * 180;
if (result > 0) {
return result;
} else {
return 360 + result;

Best regards, and thank you again !

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!