Vec3 to Hpr? How to extract length, H and P?

What is the fastest and best way to take a Vec3 and extract an Hpr from it?
Say the Vec3 is Vec3(90,90,10).
First off let me say that the R has no relavence since Vec3 is a vector starting at 0,0,0 and going to Vec3. But it will have an H and a P and a length. It would be nice to have the length too. :slight_smile:
Thanks
Douglas

Here are the current look up and down the Vec3 defs.

  def facingHprFront(self):
    #self.playerDelta=Vec3(0,0,0)
    self.playerDeltaHpr=Vec3(0,0,0)
    #camera.lookAt(Point3(self.playerDelta)+Point3(camera.getPos()))
    #camera.setHpr(getHpr(self.playerDelta))
    n = NodePath("fake")
    n.lookAt(Point3(self.playerDelta))
    camera.setHpr(n.getHpr())

  def facingHprRear(self):
    #self.playerDelta=Vec3(0,0,0)
    self.playerDeltaHpr=Vec3(0,0,0)
    n = NodePath("fake")
    n.lookAt(Point3(self.playerDelta))
    camera.setHpr(n.getHpr()+Vec3(180,0,0))

I don’t think there’s anything built into Panda to do exactly this, but it’s not too tough using basic trigonometry.

First, make two copies of the vector (call them H and P). Set the up (Z) component of H to zero, then normalize both vectors. Then:

Heading = math.atan2(H.y, H.x)
Pitch = math.atan2(P.z, math.sqrt(P.x * P.x + P.y * P.y))

I think this is right (not at a Python/Panda interpreter right now). Basically, heading is determined solely from the horizontal (X and Y) components of the vector, while pitch is determined by comparing the direction and magnitude of the vertical component (Z) with the magnitude of the horizontal components.

dont forget to convert them into degrees!

The following code will give you the range, heading and pitch to the object:

	def GetTarget(self, tgt, base):
		"""Calculate the relative range, abs heading and abs pitch from base to target."""

		# Get the relative coordinates of the NodePath.
		t = tgt.model.getPos(base);
		x = t.getX();
		y = t.getY();
		z = t.getZ();

		# Heading to target.
		a = math.degrees( math.atan2(y, x) ) + 90;
		if (a < 0):
			a += 360;

		# Range to target.
		r = math.sqrt( (x * x ) + (y * y) );
		r = math.sqrt( (r * r ) + (z * z) );

		# Azimuth to target.
		b = math.degrees( math.atan2(r, z) ) - 90;
		if (b < 0):
			b += 360;

		return r, a, b;