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.

Hello Rod,

Thank’s alot for your help! But I’m still sticking on this matter. You have always a symmetrical geometry, but I not.

Nevertheless, you have to define manually the parameter CameraPhi and CameraTheta, because you are still using the function PositionCamera().

I brought your book and find it fascinating, but I do not wanna read it from the beginning, because I do not have enough time for that!

Could you tell me, if there is some examples in your book, which are related to my issue?

Best regards

Osama

I don’t think there’s anything in the book that covers this. This post is probably your best starting point.

You should pick a center point for the scene and point the camera at that. Then you can define a radius for a sphere that defines the area of interest and use this post’s techniques to fit to that.

The interest sphere could include every object, in which case the scene might have some empty areas around the edges when seen from certain directions. You could also make the interest sphere include only the objects in the center that are most important, in which case some objects may be cut off the edges of the scene when viewed from certain directions.

Another approach would be to do the math to project the scene for the given viewing direction and then decide how far away you need to be to make it fit nicely for that viewing angle. I don’t think the book covers that and I don’t have time to give it a tray right now.

I’m also not sure there is a perfect way to do this. Sometimes you may want to crop tightly to see the center of the scene, but other times you may want to see everything. This is one of the reasons why I like to give the user control so they can adjust as needed.