How to Fit Camera to Object

I am assuming you are using a perspective camera.

You can set the camera's position, field-of-view, or both.

The following calculation is exact for an object that is a cube, so think in terms of the object's bounding box, aligned to face the camera.

If the camera is centered and viewing the cube head-on, define

dist = distance from the camera to the _closest face_ of the cube

and

height = height of the cube.

If you set the camera field-of-view as follows

fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees

then the cube height will match the visible height.

At this point, you can back the camera up a bit, or increase the field-of-view a bit.

If the field-of-view is fixed, then use the above equation to solve for the distance.


EDIT: If you want the cube width to match the visible width, let aspect be the aspect ratio of the canvas ( canvas width divided by canvas height ), and set the camera field-of-view like so

fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees

three.js r.69


To calculate how far away to place your camera to fit an object to the screen, you can use this formula (in Javascript):

// Convert camera fov degrees to radians
var fov = camera.fov * ( Math.PI / 180 ); 

// Calculate the camera distance
var distance = Math.abs( objectSize / Math.sin( fov / 2 ) );

Where objectSize is the height or width of the object. For cube/sphere objects you can use either the height or width. For a non-cube/non-sphere object, where length or width is greater, use var objectSize = Math.max( width, height ) to get the larger value.

Note that if your object position isn't at 0, 0, 0, you need to adjust your camera position to include the offset.

Here's a CodePen showing this in action. The relevant lines:

var fov = cameraFov * ( Math.PI / 180 );
var objectSize = 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) );

var cameraPosition = new THREE.Vector3(
    0,
    sphereMesh.position.y + Math.abs( objectSize / Math.sin( fov / 2 ) ),
    0
);

You can see that if you grab the window handle and resize it, the sphere still takes up 100% of the screen height. Additionally, the object is scaling up and down in a sine wave fashion (0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) )), to show the camera position takes into account scale of the object.


Based on WestLangleys answer here is how you calculate the distance with a fixed camera field-of-view:

dist = height / 2 / Math.tan(Math.PI * fov / 360);