chrischu
chrischu

Reputation: 3117

Camera distance for 3D object

Assuming I have a 3D object. I have no detailed information about the form of the object, the only information I have is the ranges of the 3 axis coordinates (the min/max x-coordinate etc.).

Given a camera "direction" (so basically from which angle does the camera look at the object) how can I calculate how far away the camera has to be to allow viewing the whole object on a screen of a certain size.

So basically I have the following inputs:

And want to calculate the camera distance.

How can I solve this?

I found a lot of information about how to project a 3D point onto a 2D plane when knowing the camera position in 3D-coordinates, but I failed in adapting the formulas in a way to match my inputs/outputs.

Example inputs would be:

Thanks in advance!

Upvotes: 1

Views: 1595

Answers (1)

D.J.Duff
D.J.Duff

Reputation: 1575

I am going to assume an orthogonal projection in the following answer, but extension to perspective projection should be easy enough. For smallish objects, orthogonal projection would look okay (since we are used to not seeing perspective effects on them).

For each point i let x[i],y[i],z[i] be the original coordinates in object space.

Let x'[i],y'[i],z'[i] be the point rotated into camera space (this can be calculated by applying your rotation transformation to each point - I think this part will be easy for you).

The orthogonal projection will be:

X[i] = f*x'[i] + Cx
Y[i] = f*y'[i] + Cy

Where f is some number, that we will calculate that deals with the scaling, and Cx and Cy are the centre of the image. This could be made more complicated to allow for e.g. perspective projection, non-unity aspect ratios. See e.g. my answer to this other question: (( 3D points projected to form an image )) for something like this dealing with perspective projection.

Since we will solve for f, we rearrange:

f = (X[i] - Cx)/x'[i]
f = (Y[i] - Cy)/y'[i]

let MaxX be the biggest desirable X point in pixel coordinates, MaxY the biggest in Y pixel coordinates, and MinX and MinY the smallest (we take the centre of the pixel).

For e.g.

MinX=0.5
MaxX=599.5
MinY=0.5
MaxY=599.5

We want to choose an f just small enough so that the most extreme x'[i] or y'[i] point maps onto one of these pixels.

NOTE: I am assuming that the object is already centred: if it is not then we will also need to calculate a good Cx and Cy too (and a tighter fit to the image can be achieved like that).

Calculate the biggest and smallest rotated points in each of the X and Y directions (min_i(x[i]) means the smallest value of x[i] over all possible values of i):

minx = min_i(x[i])
maxx = max_i(x[i])
miny = min_i(y[i])
maxy = max_i(y[i])

Now solve for the focal length that will be necessary for each of the extreme pixels to map onto each of these extreme points:

f_1 = (MinX - Cx)/minx
f_2 = (MaxX - Cx)/maxx
f_3 = (MinY - Cy)/miny
f_4 = (MaxY - Cy)/maxy

And we choose the smallest of these in order to ensure the whole object fits on the screen.

Example

If we assume that the most leftwards point (post rotation) is at

minx = -1.2

The most rightwards point:

maxx = 1.5

The most upwards point (note that I am assuming the pixel coordiantes align with spatial coordinates):

miny = -1.3

The most downards point (note that I am assuming the pixel coordiantes align with spatial coordinates):

maxy = 1.3

We use your example of a 600x600 image.

For each of these we solve for f:

f_1 = (0.5 - 300)/-1.2 = 249.6
f_2 = (599.5 - 300)/1.5 = 199.7
f_3 = (0.5 - 300)/-1.3 = 230.4
f_4 = (599.5 - 300)/1.3 = 230.4

Now we choose the smallest f and so we get:

f=199.7

And the orthogonal projection would be:

X[i] = 199.7*x'[i] + 300
Y[i] = 199.7*y'[i] + 300

A reminder: You can make this more sophisticated in many ways, by adding in perspective projection, allowing a different image centre, scaling, and so forth. This approach is designed to be the simplest way of getting started.

Upvotes: 1

Related Questions