1

My problem is the following:

Imagine I'm in the (x, y, z) position and I have several points (xn, yn, zn) and depending on my view direction, assuming I have the angle values for vertical, horizontal and roll, I want my HUD to identify said points, if they are in my view angle, and move around if any angle changes. Basically turning it to a (x, y) coordinates on the screen.

Like the quest point following behavior in the following game: https://www.youtube.com/watch?v=I_LlEC-xB50

How would I do this?

Edit: I get the coordinates using:

def convert_to_xyz(point):
  # Lat / Lon / Alt -> point[0] / point[1] / point[2]
  # Note: point[2] = earth circumference + altitude

  point[2] += _earth_radius
  x = math.cos(point[0]) * math.cos(point[1]) * point[2]
  y = math.cos(point[0]) * math.sin(point[1]) * point[2]
  z = math.sin(point[0]) * point[2]  # z is 'up'

  return numpy.array([x, y, z])

Getting the Camera Matrix:

def get_camera_matrix(fovx, fovy, height, width):
  # FOVX is the horizontal FOV angle of the camera
  # FOVY is the vertical FOV angle of the camera
  x = width / 2
  y = height / 2
  fx = x / math.tan(fovx)
  fy = y / math.tan(fovy)
  return np.array([[fx, 0, x],
                   [0, fy, y],
                   [0, 0, 1]])

Transform to camera space:

def transform_to_camera_space(point, camera_matrix):
  return np.dot(point, camera_matrix)

And then I use the @spug answer and I get values like:

array([ 133.99847154,  399.15007301])
Gonçalo
  • 144
  • 11

1 Answers1

1

Step 1:

Transform the point from world space to camera space, by multiplying it by the camera matrix. You should read up on constructing this - there are untold many web resources. In (pitch, yaw, roll) coordinates the rotations must happen in the order roll -> pitch -> yaw, which corresponds to:

  1. Rotation around X-axis through angle roll -> matrix R

  2. Rotation about Y-axis through angle pitch -> matrix P

  3. Rotation about Z-axis through angle yaw -> matrix Y

The rotational part of the camera matrix is thus given by (YPR)T, in that order of multiplication. The XYZ rotation matrices are given on this page: https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations.

The point in camera space is given by q = transpose(YPR) * (p - c), where p = (xn, yn, zn) is the point in world space, and c = (x, y, z) is your camera position. The alternative is to construct a 4x4 matrix and fill the 4th column with -(YPR)*c - again, available on the internet.

At this point, discard the point q if its X-value is below some limit (called the near clipping plane - set this to some positive value). This ensures points behind the camera are not shown.


Step 2:

Below is a diagram illustrating the process behind perspective projection:

enter image description here

  • Theta is half of FOV
  • p is depth value of point = X-coordinate in the camera frame)
  • s is Y-coordinate in the camera frame
  • X is screen coordinate

enter image description here

Similarly for Y:

enter image description here

  • t is the Z-coordinate in the camera frame
  • A is your aspect ratio (height / width)
meowgoesthedog
  • 14,670
  • 4
  • 27
  • 40
  • What do you mean with world space in "Transform the point from world space to camera space"? I have Longitude, latitude, and Altitude. Do I need to convert it into (x, y, z)? – Gonçalo Jun 27 '17 at 13:22
  • 1
    @GonacFaria 1) you said you have (x, y, z) and (vertical, horizontal, roll), not (long, lat, alt). 2) by "camera space" I mean coordinates in the camera's axes: Z-axis = camera direction, X = right direction, Y = up direction. If you still don't understand, don't worry about it, just follow the steps I have given. – meowgoesthedog Jun 27 '17 at 13:38
  • is not that I dont understand, its just that I don't see a value representation of the camera coordinates. For example, are we talking about the degrees in each pitch, yaw, roll, like (40o, 35o, 150o)? I have the camera xyz location as well as the direction it is faced and the xyz coordinates of the target. – Gonçalo Jun 27 '17 at 14:09
  • @GonacFaria yes, (pitch, yaw) specify the direction of the camera, while roll is the rotation the camera *around* that direction (imagine tilting your head sideways). I have written about how to calculate the camera rotation matrix from those 3 variables. – meowgoesthedog Jun 27 '17 at 14:14
  • Indeed you did. Its just a burst of new information and got a little bit confusing. Thank you – Gonçalo Jun 27 '17 at 14:18
  • @GonacFaria no problem; unfortunately I could not give you a clear diagram to illustrate the setup, due to my lack of artistic skill – meowgoesthedog Jun 27 '17 at 14:21
  • I understood the diagram, it was more the transformations that messed me up – Gonçalo Jun 27 '17 at 14:29
  • 1
    @GonacFaria yes I meant a diagram to illustrate how the transformations work – meowgoesthedog Jun 27 '17 at 14:37
  • I used what you said and I'm getting this kind of values array([ 0.00032714, 0.00307986]) :( – Gonçalo Jul 06 '17 at 15:19
  • 1
    @gonacfaria oops ignore my comment - the factor `2 / W` should be `W / 2`! a stupid algebraic mistake from me, sorry. and the same for `Y` and `H` – meowgoesthedog Jul 06 '17 at 15:33
  • Now I get array([ 133.99847154, 399.15007301]) ... yeah I think that was it! Thank so much! – Gonçalo Jul 06 '17 at 15:38
  • 1
    @gonacfaria good to hear; I'll fix the equations later for future reference – meowgoesthedog Jul 06 '17 at 15:40
  • Question: I have 1 point (x1,y1,0) and another one nearby as (x1, y2, 0) and when I move the yaw by 10 degrees, shouldnt the result (x, y) only move around the x, for example? Because both x and y are changing. And it doesnt make sense to me. :( – Gonçalo Jul 07 '17 at 13:50
  • @GonacFaria not *necessarily* - the Y screen coordinate will only be the same if your pitch and roll are zero - i.e. if your camera is upright and you are looking horizontally. If e.g. your camera is looking up by some angle, then the points will move along an arc as you change the yaw. It's basically the same principle that makes the sun rise and fall (if you're not on the equator) instead of just move from right to left in the sky. – meowgoesthedog Jul 07 '17 at 13:56
  • Can you join the following chat? it might be easier, https://chat.stackoverflow.com/rooms/148612/perspective-projection – Gonçalo Jul 07 '17 at 13:56
  • @GonacFaria Hi there. I fixed the code to work. Don't know if you got the email – meowgoesthedog Jul 10 '17 at 11:58
  • 1
    Yes I did saw the email, I replied. But now i noticed the email you put :). Thank you so much. It works now! :) – Gonçalo Jul 10 '17 at 12:13