<- stdout

Cameras & Planes

by

Matthew

9 views


Imagine there is a camera operator, sitting atop a crane. This camera operator can zip around the space to his heart's content. Now, let's spice things up: this camera operator uses a special camera that spills out only coordinates of its focus and its own location. Given this new conundrum how can we possibly form a picture from these numbers?

This is a problem that is encountered when dealing with virtual cameras and using some neat mathematical concepts we can decipher this seemingly unintelligible feed of numbers into a 2D image.

Before we approach this problem it is presumed that you have at least a brief introduction of 3D vectors as well as a good grounding in 2D vectors. It is also worth noting that this is not the only solution to this problem, and in-fact there is a different solution to this problem utilizing matrices; however, this is, arguably, the most easier of the two to understand given an introduction to 3D vectors.

To begin approaching this problem we can have a vector, sitting in 3D space, with the coordinates v=[111]\vec{v}=\left[ {\begin{array}{c} 1 \\ 1 \\ 1 \\ \end{array} } \right] from the origin, which would represent our focal point that the camera is pointing at given the coordinates from the camera (in this case we'll just assume they are 1, 1, 1). We can imagine this vector sitting on 3 planes, the XY-plane, XZ-plane, and the YZ-plane, which can be thought of as 2D cartesian planes sitting in 3D space connecting two axes, as shown in the following image:

xyz

Imagine the camera, represented by a vector c\vec{c}, as a light source positioned in space with its own coordinates. In this scenario, the camera would cast a shadow of v\vec{v} onto a plane, typically the ground. (This conceptualization of a camera forms the basis for perspective-based rendering and projection.)

An interesting property of a plane is that it has a normal vector n\vec{n} — a vector which sits perpendicular to the surface of the plane. In default orientation this vector aligns with one of the axes. For instance, the normal vector for the YZ-plane exclusively points in the x-direction. However, in the context of this problem the magnitude of the normal vector is not significant; our focus lies solely on its directional alignment.

Going back to the camera, if we are now to think of the 'ground' or the XY-plane being rotated such that c\vec{c}, the camera vector, is perpendicular to its surface (imagining the camera as the normal vector) allows us to determine the 'shadow' of the vector v\vec{v} — where the shadow is essentially, what the focal point would appear as in the picture.

xyz(cx;cy;cz)

Another way to think of this is by rotating a picture frame so that the camera is directly perpendicular to it, casting a shadow which burns onto the imaginary canvas. This picture would then be a reflection of the camera's perspective, much like how the sun casts shadows only from objects that are in it's view.

With the 'ground' now reoriented, we can now visualize the vector v\vec{v} with its normal vector (n\vec{n}) serving as the vertical component concerning the newly oriented plane (Keep in mind n\vec{n} is c\vec{c} since we reoriented the plane). The only missing component now is the part which lies upon the 'ground'. Sounds familiar? It should because this is our shadow!

To continue from here we need to normalize — scale — the camera vector with respect to the vector v\vec{v}, so that we can use it as a vertical component to v\vec{v} and do some vector subtraction to find the horizontal (shadow) component.

To normalize the camera vector we can use a tricky little formula for projections, which is such:

projc(v)=(vccc)cproj_{\vec{c}}(\vec{v})=(\frac{\vec{v}\cdot\vec{c}}{\vec{c}\cdot\vec{c}})\vec{c}

This interesting notation of projc(v)proj_{\vec{c}}(\vec{v}) can be read as 'the vector, c, as projected onto the vector, v.' But don't confuse this 'projected' value with the shadow, these two are quite different. This equation, at it's core, is taking the camera vector and scaling it so that it is the same height as the vector v\vec{v}, which then will allow us to solve for the shadow component.

Now that we have the vertical component we can imagine this whole thing as one big right-angle triangle. Moving the vectors around we can form a picture like this:

xyz
~v~pproj~c(~v)

Now that we have the problem simplified into a more recognizable form we can find the value of p\vec{p}, using vector subtraction, as p\vec{p} is now simply the horizontal component of a right-angle triangle.

vprojc(v)=p\vec{v}-proj_{\vec{c}}(\vec{v})=\vec{p}

However, we can't stop at just finding p\vec{p}, as we could move this camera extremely close to v\vec{v} and get the same result since the c\vec{c} gets normalized; therefore, we must apply an additional scalar to account for the distance dd, that the camera is away from the vector v\vec{v}.

This scalar is just an arbitrary value that we can give, which will determine how sensitive our system will be to changes in distance, a simple solution to this would just be by using the reciprocal of the distance, with an extra case to account for zero distance, as such:

pv={1dpd00d=0\vec{p}_v = \begin{cases} \frac{1}{d}\cdot\vec{p} & d\neq 0 \\ 0 & d=0 \end{cases}

Using all of these parts we can piece together what the 'shadow' vector would be, producing a vector that changes based on the perspective of the camera, giving us a picture of what that vector looks like from any perspective.