001/* 002 003*/ 004 005package renderer.pipeline; 006import renderer.scene.*; 007 008import java.util.List; 009 010/** 011 Project each {@link Vertex} of a {@link Model} from camera 012 coordinates to the {@link Camera}'s image plane {@code z = -1}. 013<p> 014 Let us derive the formulas for the perspective projection 015 transformation (the formulas for the parallel projection 016 transformation are pretty obvious). We will derive the 017 x-coordinate formula; the y-coordinate formula is similar. 018<p> 019 Let {@code (x_c, y_c, z_c)} denote a point in the 3-dimensional 020 camera coordinate system. Let {@code (x_p, y_p, -1)} denote the 021 point's perspective projection into the image plane, {@code z = -1}. 022 Here is a "picture" of just the xz-plane from camera space. This 023 picture shows the point {@code (x_c, z_c)} and its projection to 024 the point {@code (x_p, -1)} in the image plane. 025<pre>{@code 026 x 027 | / 028 | / 029 x_c + + (x_c, z_c) 030 | / | 031 | / | 032 | / | 033 | / | 034 | / | 035 | / | 036 x_p + + | 037 | / | | 038 | / | | 039 | / | | 040 | / | | 041 | / | | 042 +-----------+-------------+------------> -z 043 (0,0) -1 z_c 044}</pre> 045<p> 046 We are looking for a formula that computes {@code x_p} in terms of 047 {@code x_c} and {@code z_c}. There are two similar triangles in this 048 picture that share a vertex at the origin. Using the properties of 049 similar triangles we have the following ratios. (Remember that these 050 are ratios of positive lengths, so we write {@code -z_c}, since 051 {@code z_c} is on the negative z-axis). 052<pre>{@code 053 x_p x_c 054 ----- = ----- 055 1 -z_c 056}</pre> 057<p> 058 If we solve this ratio for the unknown, {@code x_p}, we get the 059 projection formula, 060<pre>{@code 061 x_p = -x_c / z_c. 062}</pre> 063<p> 064 The equivalent formula for the y-coordinate is 065<pre>{@code 066 y_p = -y_c / z_c. 067}</pre> 068*/ 069public class Projection 070{ 071 /** 072 Project each {@link Vertex} from a {@link Model} to 073 the {@link Camera}'s image plane {@code z = -1}. 074 075 @param vertexList {@link List} of {@link Vertex} objects to project onto the image plane 076 @param camera a reference to the {@link Scene}'s {@link Camera} object 077 */ 078 public static void project(List<Vertex> vertexList, Camera camera) 079 { 080 // Mutate each Vertex object so that it contains 081 // projected (x,y) coordinates. 082 for (Vertex v : vertexList) 083 { 084 if ( camera.perspective ) 085 { 086 // Calculate the perspective projection. 087 v.x = v.x / -v.z; // xp = xc / -zc 088 v.y = v.y / -v.z; // yp = yc / -zc 089 v.z = -1; // zp = -1 090 } 091 else 092 { 093 // Calculate the parallel projection. 094 // xp = xc 095 // yp = yc 096 v.z = 0; // zp = 0 097 } 098 } 099 } 100}