Title: Automatically set camera distance in WPF and C#
This example extends the post Build a geodesic sphere with WPF and C# to let you automatically set the camera distance to make the scene fill the viewport.
Making a 3D scene fill the viewport nicely can be tricky. The basic idea is to position the camera the right distance from the scene to give a good result. However, some scenes are asymmetric so the "best" distance will depend on the angle from which you are viewing the scene.
One approach that often gives fairly good results is to use the camera's field of view and the radius of the scene's bounding sphere to set the camera distance. To do that, you need to know how the field of view works.
Field of View
The picture on the right shows how the camera's field of view affects the drawing. The field of view is the (horizontal) angle that the camera can see. Here width is the width of the viewport and distance is the distance between the camera and the virtual viewing plane. For our purposes, distance is the camera distance, or the distance between the camera and the center of the scene's objects.
Simple trigonometry gives us:
If we solve for distance, we get:
In order to make the scene's objects fill the viewport, we set the distance so the width/2 is the radius of the scene's bounding sphere.
C# Code
When you click the program's Set Size button, the following code executes.
private void btnSetSize_Click(object sender, RoutedEventArgs e)
{
const double width = 2.5;
double fov_radians = TheCamera.FieldOfView * Math.PI / 180.0;
double distance = (width / 2) / Math.Tan(fov_radians / 2);
const double distance_scale = 1.0;
CameraR = distance * distance_scale;
lblDistance.Content = CameraR.ToString("0.0");
PositionCamera();
}
This example's scene is a geodesic sphere with some axes. The axes extend to points 1.25 units away from the origin, so I'm giving the bounding sphere for this example a radius of 1.25 or a diameter of 2.5. That means the desired width value should be 2.5.
The camera's FieldOfView property holds the field of view in degrees but the Math.Tan function needs its input angle in radians, so the program converts the field of view value into radians.
Next the code uses the formula shown earlier to calculate the desired camera distance. It then sets the camera distance to that value multiplied by a scale factor. You can use the scale factor if you want to add or subtract a little distance to make your scene look better. This example looks okay without scaling, so distance_scale is set to 1.0.
The code finishes by displaying the new distance and repositioning the camera to show the new result.
Summary
Automatically setting camera distance can be tricky depending on the objects in your scene. This example calculates a camera distance from the camera's field of view and a bounding sphere diameter (width). You can add a scale factor to adjust the result if that makes sense for your scene.
For more information on creating three-dimensional scenes with WPF and C#, see my book WPF 3d.
Meanwhile, download the example to see additional details and to experiment with it.
Download the example to experiment with it and to see additional details.
|