2
$\begingroup$

I'd like to get the inclination of a point from the camera's plane of rotation (defined by the local y-axis).

The code I currently have to works sometimes, but not always. It works when the camera is at the global origin, but not always otherwise. Here I have a point of type Vector, and a camera.

import math
camera = ...
point = ...

point_in_local_coords = ( camera.matrix_world.inverted() * point )
angle_to_normal = Vector( (0,1,0) ).angle( point_in_local_coords )
angle_to_plane_of_rotation = math.pi / 2. - angle_to_normal

In particular, I have

point = Vector( (-1.8580, -0.9115, 3.6539) )
camera.location = (0.104775, -2.752501, 1.390733)
camera.rotation_euler = Euler( (1.5293482542037964, -0.022381655871868134, -0.09930113703012466), 'XYZ' )

yields pitch=42.5164 degrees. I tested whether this is correct by creating an empty at the location of point, and varying the camera's field of view until the empty is in frame. Since the empty is not in frame when the camera's FOV is 96 degrees (> 42.5 * 2), I know the true pitch must be larger than the one I calculated.

My question is, what is the correct way to calcualate the pitch of a point relative to the plane of rotation defined by the camera's Y axis. Bonus points if you explain where I went wrong :)

Version info:

Blender 2.78 (sub 0)
build hash: 0b13b7a

--------UPDATE---------------

Problem solved. I didn't consider that the elevation of a point from the camera's plane of rotation is constant, but that the apparent pitch will vary as the camera rotates. In my case, the FOV can shrink as the camera approaches the point, and must grow as it rotates away. This is a 'duh' thing, but that's what I forgot about. So my testing procedure was the problem :o

Both the suggested method, the initial method, and a myriad of other ways work - so I've accepted the proposed answer. Thanks for your help!

$\endgroup$

1 Answer 1

1
$\begingroup$

Compute the distance between the camera and the point projected onto the plane, i.e. d = point_in_local_coords.xz.length. Then compute the angle using a = atan(d, point_in_local_coords.y).

For bonus points: where you went wrong is the assumption that the angle you want to compute is unaffected by the point's local x and z coordinates.

PS: I'm typing this on my phone, without Blender to test, so I might have a typo in my math somewhere.

$\endgroup$
1
  • 1
    $\begingroup$ Thanks for pointing out point_in_local_coords.xz! I did not know about that, and it's a good tip. Testing this out yields the same answer of 42.5, but the FOV method suggests the true answer should be something between 43.5 and 44 degrees. However, I assumed that you meant a = atan( point_in_local_coords.y / d ). $\endgroup$
    – user32344
    Commented Dec 8, 2016 at 19:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .