The perspective projection obeys the laws of linear perspective. In 3DLDF, it is performed by means of a transformation, whose effect is, to the best of my knowledge, exactly equivalent to the result of a perspective projection done by hand using vanishing points and rulers.
It is very helpful to the artist to understand the laws of linear perspective, and to know how to make a perspective drawing by hand.^{1} However, it is a very tedious and error-prone procedure (I know, I've done it). One of my main motivations for writing 3DLDF was so I wouldn't have to do it anymore.
[next figure] shows a perspective construction, the way it could be done by hand. The point of view, or focus is located 6cm from the picture plane, and 4cm above the ground (or x-z) plane at the point (0, 4, -6). The rectangle R lies in the ground plane, with the point r_0 at (2, 0, 1.5). The right side of R, with length = 2cm lies at an angle of 40 to the ground line, which corresponds to the intersection line of the ground plane with the picture plane, and the left side, with length = 5cm, at an angle of 90 degrees - 40 degrees = 50 degrees to the ground line.
Fig. 56.
While it's possible to use 3DLDF to make a perspective construction in the traditional way, as [the previous figure] shows, the code for [next figure]
achieves the same result more efficiently:
default_focus.set(0, 4, -6, 0, 4, 6, 6); Rectangle r(origin, 2, 5, 0, 40); Point p(2, 0, 1.5); r.shift(p - r.get_point(0)); r.draw();
Fig. 57.
In [the second-to-last figure]
, it was
convenient to start with the corner point r_0;
if we needed the center of R, it would have to be found from the
corner points.
However, in 3DLDF, Rectangles
are most often constructed about
the center. Therefore, in [next figure]
, R is first
constructed about the origin, with the
rotation about the y-axis passed as an argument to the constructor.
It is then shifted such that *(
R.points[0])
, the first
(or zeroth, if you will) Point
on R comes to lie at
(2, 0, 1.5).
Unlike the other transformations currently used in 3DLDF, the perspective transformation is non-affine. Affine transformations maintain parallelity of lines, while the rules of perspective state that parallel lines, with one exception, appear to recede toward a vanishing point.^{2}
In [the second-to-last figure] , the lines from r_0 to r_1 and from r_3 to r_2 appear to vanish toward the right-hand 40 degrees vanishing point, while the lines from r_0 to r_3 and from r_1 to r_2 appear to vanish toward the left-hand 50 degrees vanishing point. The lower the angle of a vanishing point, the further away it is from the center of vision, as [next figure] shows:
Fig. 58.
In [the previous figure] , the 0.5 degrees vanishing point is nearly 5 and 3/4 meters away from the CV, and a line receding to it will be very nearly horizontal. However, the distance from the focus to the CV is only 5cm. As this distance increases, the distance from the CV to a given vanishing point increases proportionately. If the distance is 30cm, a more reasonable value for a drawing, then the x-coordinate of VP 10 degrees is 170.138cm, that of VP 5 degrees is 342.902cm, and that of VP 0.5 degrees is 3437.66cm! This is the reason why perspective drawings done by hand rarely contain lines receding to the horizon at low angles.
This problem doesn't arise when the perspective transformation is used. In this case, any angle can be calculated as easily as any other:
default_focus.set(0, 4, -6, 0, 4, 6, 6); Rectangle r; Point center(0, 2); r.set(center, 2, 5, 0, 0, 0.5); r.draw(); r.set(center, 2, 5, 0, 0, 2.5); r.draw(); r.set(center, 2, 5, 0, 0, 5); r.draw(); current_picture.output();
Fig. 59.
There are many books on linear perspective for artists. I've found Gwen White's Perspective. A Guide for Artists, Architects and Designers to be particularly good. Vredeman de Vries, Perspective contains beautiful examples of perspective constructions.
(I believe the following to be correct, but I'm not entirely sure.) Let vector v be the line of sight. By definition, the plane of projection will be a plane p, such that vector v is normal to p. Let q_0 and q_1 be planes such that q_0 == q_1 or q_0 || q_1, and q_0 is perpendicular to p. It follows that q_1 is perpendicular to p. Let l_0 and l_1 be lines, such that l_0 != l_1, l_0 || l_1, l_0 lies within q_0, l_1 lies within q_1, l_0 is perpendicular to vector v, and l_1 is perpendicular to vector v. Under these circumstances, the projections of l_0 and l_1 in p will also be parallel.