Alright, good work with the implementation - I’ll take a look at it tomorrow if needed, since now it’s a bit late here. In the meantime, regarding computing the said offsets (well, actually, the apparent size in terms of distance between the top and bottom visible points on the sphere, since you can then easily figure out the rest) it’s just simple right triangle math. And yes, δ is camera.fov
.
[I had a nice photoshop figure explaining things, but I accidentally closed it without saving it first (which is not something I normally do), so I’ll explain using your figure, although you’d have to imagine things or write the schematics on a piece of paper instead, for easier understanding.]
First, let’s call the camera point C
, the center of the sphere O
and the points where the tangents touch the sphere A
and B
(up and down, respectively), with the AB segment intersecting the CO
(of length D
) in a point called X
. What you need for the apparent length is the AB segment length, instead of d
(which is basically R * 2
, with R
being the sphere radius), so if you know the length of AX, you multiply that with 2 and get AB
.
Now, you can easily notice that the CAO
and CBO
triangles are right triangles, and so are the CAX
and CBX
ones, or the OAX
and OBX
ones. In a right triangle, the sides can be expressed as either hypothenuse * sin(oppositeangle)
or hypothenuse * cos(adjacentangle)
to the said side. That’s the reason for the δ
or fov
formula in the apparent diameter for the sphere, because you have the CAO
right triangle where AO = CO * sin(ACO)
aka d / 2 = D * sin(δ / 2)
, thus sin(δ / 2) = d / 2 * D
and then applying arcsin
becoming δ / 2 = arcsin(d / 2 * D)
. You may also notice that in this triangle, the COA
angle is 90 degrees minus the other acute angle aka half of the fov, so by extension the XOA
angle has the same value, PI - δ / 2
.
On the second right triangle of interest, i.e. OAX
, given the fact that we know the value of the hypothenuse (d / 2
or R
) and the opposite angle of the AX
segment aka the XOA
angle (PI - δ / 2
), it becomes clear that AX = d / 2 * sin(PI - δ / 2) = R * sin(PI - δ / 2)
, or even R * cos(δ / 2)
if you find it easier.
Now you can multiply by 2 the above value and get the “length” of the apparent diameter, as 2 * R * sin(PI - δ / 2) = 2 * R * cos(δ / 2)
. In other words, you’ll need to multiply the actual diameter d
with either sin(PI - δ / 2)
or cos(δ / 2)
to get the visible diameter.