# Why an object becomes larger when drawn in perspective

I am following David Salomon's book "Transformations and Projections in Computer Graphics" where it is explained how to project a 3d object to the 2d canvas in perspective:

Define a point for the viewer on the negative z-axis, a distance k away from the origin; Define the canvas as the x-y plane; Draw a line connecting a point on the object to the viewer and mark the intersection of this line with the x-y plane. This new point is the corresponding point when drawn in perspective.

I have done exactly that for a cube with the help of a geometry software (GeoGebra) and added an option to change the value of k, the location of the viewer.

Then I realized that the object actually looks larger on the canvas when k is increased. This is in contradiction to the expected illusion of perspective - objects further away should look smaller.

I would like to have your opinion about why it is so in my case.

** The drawing on the right hand side was created by following the exact procedure I explained above.

If you keep constant the scale at which you view the x-y plane (image plane), while changing the distance of the viewpoint to that plane, then you are not solely changing the viewpoint position; you are also changing the field of view (FOV). Here is an “overhead” view of the effect you're getting. Notice that the solid horizontal line (representing your x-y plane) is the same length in both cases.

When the viewpoint is far from the plane (k is large), the object is closer to the edge of the visible image. (In the limit $$k = \infty$$, this becomes an orthographic projection.) When k is smaller, the FOV widens, meaning that objects in the same “world” position get projected to regions of the image closer to the center — notice where the lines of intersection between the box and the image plane are.

In order to avoid changing the field of view, what you must do is keep k constant (relative to the size of the image plane), but instead translate both the viewpoint and the image plane — or, equivalently, translate all the displayed objects in the opposite direction.

Here is how FOV expressed as angle relates to k:

$$\theta$$ is the FOV angle. Notice that the lines $$k$$ and $$w$$ (width) form a pair of right triangle. Split the picture down the middle and basic right-triangle trigonometry tells us that

\begin{align} k &= r \cos(\theta/2) \\ w/2 &= r \sin(\theta/2) \\ \end{align}

for some radius $$r$$ which is irrelevant (there is no physical circle). Solving these to relate $$k$$ and $$w$$ gives us:

$$w/2 = \tan(\theta/2) \cdot k$$

This is how FOV is actually computed in the practice of real-time GPU graphics: a $$k$$ is chosen (called the “near plane” for unrelated reasons, chosen to be closer to the camera than any object in view), then the width and height of the rectangle (actually one face of a frustum) are chosen based on the desired FOV and $$k$$.

• Thanks for your answer. I stated in the question a couple of steps one should perform to project a point in 3d to 2d. Is there in it a missing step? I agree with you that no cone of view has been defined in it. Suppose I want to work with a 60° cone of view. Then how should I correctly project the vertices using geometrical constructions as I have already done to produce this figure?
– tush
Commented Feb 28, 2023 at 14:14
• @tush "Is there in it a missing step?" Yes, the step of translating the objects relative to the image plane in order to move the camera. The procedure you implemented produces a particular perspective projection. But in order to move the viewpoint in space without also changing the projection, you need to move the image plane and the viewpoint simultaneously (or equivalently move the viewed objects oppositely), not only the viewpoint. Commented Feb 28, 2023 at 16:45
• I've added a section to my answer about precisely how FOV relates to the parameters you're working with. Commented Feb 28, 2023 at 16:46
• Thanks for that. Though I still don't understand how differently I need to project a point to the canvas. I first don't want to vary the value of k. It seems to that I am missing a crucial step; It is not just "intersect a ray from the 3d point with the xy plane" - there is another step that I am not aware of.
– tush
Commented Feb 28, 2023 at 17:08
• @tush Translation is a separate step from projection. You don't modify the projection; you translate the objects before projecting them. (A geometry construction tool may not be the best way to experiment with this.) Or you can also see it as as moving the plane onto which the points are projected (exactly the same amount as you move the viewpoint) — this is the same thing with a different choice of coordinate system. Commented Feb 28, 2023 at 18:45

As nicely stated by Kevin Reid, the field of view is not accounted for in the figures I uploaded.

In order to get the correct coordinates for the projected points on the $$x-y$$ plane, one should also divide each component by the half width of the screen:

If $$\mathbf{P}=\left(P_{x},P_{y},P_{z}\right)$$ is the point in 3d and $$\mathbf{P^{*}}\in\mathbb{R}^{2}$$ is its projection, then $$P^{*}=\left(\frac{x_{P}}{\left(\frac{z_{P}}{k}+1\right)\frac{w}{2}},\frac{y_{P}}{\left(\frac{z_{P}}{k}+1\right)\frac{w}{2}}\right)=\left(\frac{x_{P}}{\tan\frac{\theta}{2}\left(k+z_{P}\right)},\frac{y_{p}}{\tan\frac{\theta}{2}\left(k+z_{P}\right)}\right)$$

In the figure I provided, the coordinates for the $$\mathbf{P^{*}}$$ where almost similar, except of the scaling factor due to the finite width of the screen: $$P^{*}=\left(\frac{x_{P}}{\left(\frac{z_{P}}{k}+1\right)},\frac{y_{P}}{\left(\frac{z_{P}}{k}+1\right)}\right)$$

Referring back to David Salomon's book, in §3.10, the cone of view (or viewing volume) is indeed mentioned but only in regard to “clipping” — to determine which points are outside the viewing volume and therefore to determine whether they should be displayed or not. Aside from that I couldn't find in his book the missing part I was looking for in this question.