views:

447

answers:

4

Heyo,

I'm currently working on a project where I need to place the camera such that the full motion of a character would be viewable without moving the camera. I have the position where the character starts, as well as the maximum distance that the character will travel in all three directions (X,Y, & Z). I also have the field of view (which is 90 degrees).

Is there an equation that'll figure out where I need to place the camera so it won't have to move to see the full motion?

Note: this is using OpenGL.

Clarification: The camera should be "in front" of the character that's in the motion, not above.

It'll also be moving along a ground plane.

A: 

Take the line segment from the startpoint to the endpoint. Construct a plane orthogonal to this line segment through the midpoint of the line segment. Then position the camera somewhere in this plane at an distance of more than the following from the intersection point of plane and line looking at the intersection point. The up vector of the camera must be in the plane and the horizontal field of view must be 90 degrees.

distance = sqrt(dx^2 + dy^2 + dz^2) / 2

This camera positions will all have the startpoint and the endpoint on the left or right border of the view port and verticaly centered.

Another solution might be to write a function that takes the startpoint, the endpoint, and the desired position of both points on the screen. Then just solve the projection equation for the camera transformation.

Daniel Brückner
A: 

Simply having the maximum range of (X, Y, Z) is not on its own sufficient, because the viewing port is essentially pyramid shaped, with the apex of the pyramid being at the eye position.

For the sake of argument, let's assume that all movement is in the (X, Z) plane (i.e. the ground), and the eye is directly above the origin 10m along the Y axis.

Assuming a square viewport, with your 90˚ field of view you'd be able to see from ±10m along both the X and Z axis, but only for objects who are on the ground (Y = 0). As soon as they come off the ground your view is reduced. If it's 1m of the ground then your (X, Z) extent is only ±9m.

Clearly a real camera could be placed anyway in the scene, facing any direction. Even the "roll" angle of the camera could change how much is visible. There are actually infinitely many such camera points, so you will need to constrain your criteria somewhat.

Alnitak
A: 

It depends, for example, if the object is gonna move in a plane, you can just place the camera outside a ball circumscribed its movement area (this depends on the fact that FOV is 90, which is a fortunate angle).

If the object is gonna move in 3D, it's much more difficult. It would help if you'd specify the region where the object moves (cube vs. ball...) and the direction you want to see it from.

jpalecek
+1  A: 

If you make a bounding sphere of the points, all you need to do is keep the camera at a distance greater than or equal to the radius of the bounding sphere / sin(FOV/2).

For example, if you have a bounding sphere with radius Radius, and a specified Field of View FOV, your camera just needs to be at a point "Dist" away, pointing towards the center of the bounding sphere.

The equation for calculating the distance is: Dist = Radius / sin( FOV/2 );

This will work in 3D, for a camera at any orientation.

Reed Copsey
This works, but it's a pessimistic approach - eg. if the object is approaching you on a line, you can place the camera just at the endpoint.
jpalecek
He mentioned that everything was moving around in 3D, so I'm guessing it won't be completely linear...
Reed Copsey
@Reed: Correct, the motion can move 5 units to the left, 3 units to the right, 6 units up, 4 units down, etc.
Will Mc
@Reed (again!): So one approach would be to set the radius equal to the max of the max X, max Y, max Z distances? aka: max(maxX, maxY, maxZ)?
Will Mc
@reed - that's not quite right - the viewing pyramid would intersect the sphere at the edges.
Alnitak
@Reed: even if it's not completely linear, it's still pessimistic - eg. you can survey a cube from one of its corners with a FOV of 90 degrees (~70 would suffice), which is much nearer than what you suggest (by a factor of sqrt(2) with FOV 90)
jpalecek
@Alnitak: At exactly the distance, it will intersect at the edges, but you should always be guaranteed to see every point. Using a distance slightly further will guarantee that the points are always inside the frustum. Good point.
Reed Copsey
@jpalecek: This is a pessimistic, non-optimal approach. Given teh constraints of the question, it's how I'd go about it, though. There are "better" views, since you could potentially be much closer, and rotate, etc - but this will work for any specified view, and is simple to implement.
Reed Copsey
@Will Mc: That will work,but be overly pessimistic. You'd ideally want the minimum bounding sphere (which can be googled), but you could just use the centroid of the points as the center and the maximum distance to one of your x/y/z coordinates as the radius (much smaller sphere than max distances)
Reed Copsey