‘sin’ does not just give better results, it is the right trigonometric function to use.
For the code you need to know:
- width:height aspect ratio (width / height as floating point number as used by gluPerspective)
- center and radius of the bounding sphere for the scene
- direction of the camera (unit length)
- fov in y (as used by gluPerspective)
The code would be as follows:
half_min_fov_in_radians = 0.5 * (fov * PI / 180);
if (aspect < 1.0)
{
// fov in x is smaller
half_min_fov_in_radians = atan(aspect * tan(half_min_fov_in_radians));
}
distance_to_center = radius / sin(half_min_fov_in_radians);
eye = center - dir * distance_to_center;
You may also take advantage of that information to fit your zfar clipping plane (if you do not want to keep it too far).
zfar = distance_to_center + radius;
if (zfar < 1.5 * znear)
{
// Keep zfar always bigger than znear
zfar = 1.5 * znear;
}