Without having looked at all the complicated code of Helmut Dersch, I found two lines of code from which I assume that the optimizer realizes the combination 2A, i.e.
The hfov is measured from the left of the left pixel area to the right of the right pixel area . The reference point is in the mid of the pixels.
These lines are in the file adjust.c:
First (in function distSphere() ):
h2 = (double)optInfo->im[ n[j] ].height / 2.0 - 0.5;
w2 = (double)optInfo->im[ n[j] ].width / 2.0 - 0.5;
execute_stack_new( (double)optInfo->cpt[num].x[j] - w2, // cartesian x-coordinate src
(double)optInfo->cpt[num].y[j] - h2, // cartesian y-coordinate src
&x, &y, stack);
This corresponds to my terms x - (W-1)/2 that occur in the cases 2A and 1A.
Second (in function SetInvMakeParams() ):
case _rectilinear:
mp->distance = (double) pn->width / (2.0 * tan(b/2.0));
break;
Probably this mp->distance is some kind of distance D that is used when modelling the camera with a simple pinhole model.
In the pinhole model the angle alpha would be calculated as: alpha = arctan( x / D ) where D is the distance of the optical center (the pinhole) to a plane parallel to the image plane and going through the point in 3D space.
Here D = mp->distance .
If you insert it, you get:
alpha = arctan ( ( x - (W-1)/2 ) / mp->distance ) = arctan ( ( x - (W-1)/2 ) / (W / (2*tan(b / 2))) ) .
Here b is hfov in radians, so I call it hfov_rad ( in the C-Code hfov is used with the unit degrees ).
So:
alpha = arctan ( ( x - (W-1)/2 ) / (W / (2*tan(hfov_rad / 2))) ) = arctan( (x - (W-1)/2) / (W/2) * tan(hfov_rad / 2) )
This is exactly the same as in my case 2A, so I assume that the case 2A is realized in the optimizer.
Maybe I will also test it with numerical values.