Convert Vector to Hpr?


Is there ANY way to convert a vector to a Hpr value?
I tried EVERYTHING, including sine/cosine calculations.


A vector has three degrees of freedom, which could be interpreted as heading, pitch and length (spherical coordinates). This assumes a “look in the same direction as the vector” semantic. So, there is one information that is not used: length. And for computing hpr something is missing: roll.

Transforming cartesian coordinates (x,y,z) to spherical coordinates should do the trick, but sine/cosine are slow.

NodePath.lookAt( x, y, z ) should be a faster way to transform (x,y,z) to (hpr). Just call in relative to the NodePath if you have a vector and not a point.

Hope this is helpful

Thanks a lot!
But… I don’t want my object to rotate, but I just want the hpr value.
Should I create a dummy node then?

what do you need the hpr value for?
Anyway, try something like this:
Your vector has an origin. If you just have a plain vector its origin is (0,0,0).
You you have some kind of velocity vector that vector would be relative to the model whos velocity the vector represents.
In either way you have an origin. You can think of your vector as a point in some coordinate system.
You can further think of this point as being rotated around its origin.
To retrieve the Hpr of your vector you would simply write:


First make sure the vector is normalized (length = 1). Then try these formulas:

H = atan2(X, Y) * 180 / 2.14159
P = asin(Z) * 180 / 2.14159
R = 0

As stated in a previous post, this assumes no roll. You may need to to flip the sign of X and/or Y in the calculation of heading. Also note that if the vector is ever completely vertical (X = Y = 0) you will get bad results for heading.

@Legion: AttributeError: ‘libpanda.Vec3’ object has no attribute ‘getHpr’

Thanks for your help! (I don’t need pitch and roll, just heading)
But erhmm… what is 2.14159… ?
Sounds like a mix-up between pi and euler;)
and erhmm it rotates the wrong way.
The correct code must be:
H = -atan2(X, Y) * 180 / math.pi
This works fine;) Thanks again for your help:D

Yep, I meant Pi. Glad it works.

another problem.
How to convert it back? :smiley:

Since you seem to be using vectors in the plane (pitch = 0, roll = 0), this should work:

X = sin(H / 180 * math.pi)
Y = cos(H / 180 * math.pi)
Z = 0

This should be right, but if there’s a problem you probably need to just flip the sign on X or Y, or possibly flip the sin and cos.

Arkaein, thanks a million times! :slight_smile: :smiley: