# Why are angle measurements so different? (Camera sensor dimensions problem)

There are two points A and B, their coordinates are known.

I calculate the coordinates of these points on the camera sensor and I find the angle at which the AB is visible in the camera.

For some reason, this angle differs from that shown by Blender as the angle of a triangle constructed at these two points and the position of the camera. At other positions of the camera or points A and B, the angle at which the AB is visible is a few degrees larger than it actually is.

Can anyone explain to me why this is so? Is it just a bug and I need to report a bug.

import bpy
from bpy_extras.object_utils import world_to_camera_view as wcv
from math import sqrt, acos, degrees, atan

scn = bpy.data.scenes['Scene']
point_1_loc = bpy.data.objects['Empty'].location
point_2_loc = bpy.data.objects['Empty.001'].location
point_cam_loc = bpy.data.objects['Camera'].location
cam = scn.camera
print('============================================')
x1, y1, z1 = point_1_loc
x2, y2, z2 = point_2_loc
x3, y3, z3 = point_cam_loc
ABsq = (x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2
ACsq = (x1-x3)**2 + (y1-y3)**2 + (z1-z3)**2
BCsq = (x3-x2)**2 + (y3-y2)**2 + (z3-z2)**2
angleACB = acos((ACsq + BCsq - ABsq)/(2*sqrt(ACsq*BCsq)))
print(f'angle ACB is equal to {degrees(angleACB)} degrees')

# focus distanse - 50 mm
# sensor width - 36 mm
# sensor height - 24 mm

# 418, 400     1146, 965

x0, y0 = 18, 12 # center of sensor - O
x1, y1, _ = wcv(scn, cam, point_1_loc) # point 1 coords on sensor - A
#x1, y1 = 418/1920, 400/1080
x1 *= 36
y1 *= 24
x2, y2, _ = wcv(scn, cam, point_2_loc) # point 2 coords on sensor  - B
#x2, y2 = 1146/1920, 965/1080
x2 *= 36
y2 *= 24

OAsq = (x0-x1)**2 + (y0-y1)**2
OBsq = (x0-x2)**2 + (y0-y2)**2
ABsq = (x2-x1)**2 + (y2-y1)**2

CAsq = 2500 + OAsq
CBsq = 2500 + OBsq
angleACB = acos((CAsq + CBsq - ABsq) / (2*sqrt(CAsq*CBsq)))
print(f'AB is visible at an angle of {degrees(angleACB)} degrees')

# REZULTS
# ============================================
# angle ACB is equal to 17.93093031126681 degrees
# AB is visible at an angle of 19.322813969671525 degrees • I think I know what's up, but I'd like to verify it against your actual blend file. Can you add it to your question? (How to add a blend file) Oct 30, 2021 at 23:38
• I didn't check if your math is correct, but more importantly, perspective projection does not preserve angles so you should not expect them to be the same. For example, imagine what happens if you have a very narrow triangle inside a very narrow viewing frustum (so narrow one leg of the triangle reaches from one edge to the other). Oct 31, 2021 at 15:05
• It's a simple math if there is no optical distortion or other thing. So... what is math inside Blender? The results from bpy_extras.object_utils.world_to_camera_view and calculated from rendered picture are the same. But they're supposed to be the same with geometric angle as well.
– JABA
Oct 31, 2021 at 19:13
• The code for world_to_camera_view is here. I think it works like this. Which means angles aren't preserved. I'm not sure I understood your diagrams though... Oct 31, 2021 at 21:25
• OK! I've got the point. I took the dimensions of the sensor 36x24, but I did not take into account the crop factor of 16:9. Now it werx.
– JABA
Oct 31, 2021 at 23:24

It is not very clear what is happening with the camera in the blender. When you enter a command in console bpy.data.scene['Scene'].camera.sensor_width, bpy.data.scene['Scene'].camera.sensor_height, you get 36 to 24, respectively.
But in fact when you check to show "Sensor" in the "Viewport Display" you can see that the sensor is square with a crop factor such as camera resolution. i.e. 16:9. So sensor dimensions is 36 x 20.25. Now I can get what I expected.