%Orthographic.m
%This program paints copies of a photo on three sides 
%of a cube using an orthographic projection. %It is important to know that this program has been %designed to emphasize the mathematics we have %been discussing and it does not use MATLAB's built-in %tools for rendering three dimensional %objects. Readers who are knowledgable about MATLAB %or another programming language may %wish to design a more efficient program. %Although a z-buffer is not needed for this %particular object, one is included in order to make the %program more easily adaptable. %In the first line the photo is read into memory. %The word 'infile' should be replaced by the %filename of your image file which must be stored in %the current directory. Next, we find the %dimensions of the input photo. We also find the %edge size to make a square.
inpic=imread('infile');
row = size(inpic,1);
col = size(inpic,2);
s=min(row,col);
%In the following lines we fix the parameters 
%that determine the direction to the viewer's eye.
theta=pi/3;			%theta is called the azimuth angle.
phi=pi/2-pi/9;			%phi is the complement of the angle of elevation.
a=cos(theta)*sin(phi);
b=sin(theta)*sin(phi);
c=cos(phi);			%(a,b,c) gives the direction from the origin to the eye.
%We enter estimated bounds on the computed coordinates, 
%initialize the output file by assigning 
%the color (255,255,255) to each pixel 
%(rescales to (1,1,1) -- white), 
%and initialize the z-buffer 
%array by entering -Inf for negative infinity.
c1min=-2*s;
c1max=3*s;				%Chosen so c1min < coef1 < c1max.
c2min=-2*s;
c2max=3*s;				%Chosen so c2min < coef2 < c2max.
outpic(1:round(1+c2max-c2min),1:round(1+c1max-c1min),1:3) = 255;
zbuffer(1:round(1+c2max-c2min),1:round(1+c1max-c1min)) = -Inf;
for i=1:s
 for j=1:s
%Front face:
x0=s;		y0=j;		z0=s-i+1;
%Orthographic projection routine starts here. 
coef1=-sin(theta)*x0+cos(theta)*y0;
coef2=-cos(theta)*cos(phi)*x0-sin(theta)*cos(phi)*y0+sin(phi)*z0;
distance= x0*a+y0*b+z0*c;		%This scalar projection plays the role of a distance.
    if (c1min<=coef1 & coef1<=c1max    & c2min<=coef2 & coef2<=c2max)
 	if distance > zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))
 			outpic(round(1+c2max-coef2),round(1+coef1-c1min),:)=inpic(i,j,:);
 		zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))=distance;
	end
	end
%Orthographic projection routine ends here.
%Right face:
x0=s-j+1;	y0=s;		z0=s-i+1;
%Orthographic projection routine starts here. 
coef1=-sin(theta)*x0+cos(theta)*y0;
coef2=-cos(theta)*cos(phi)*x0-sin(theta)*cos(phi)*y0+sin(phi)*z0;
distance= x0*a+y0*b+z0*c;		%This scalar projection plays the role of a distance.
    if (c1min<=coef1 & coef1<=c1max &    c2min<=coef2 & coef2<=c2max)
 	if distance > zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))
 			outpic(round(1+c2max-coef2),round(1+coef1-c1min),:)=inpic(i,j,:);
 		zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))=distance;
	end
	end
%Orthographic projection routine ends here.
%Top face:   
x0=i;		y0=j;		z0=s;
%Orthographic projection routine starts here. 
coef1=-sin(theta)*x0+cos(theta)*y0;
coef2=-cos(theta)*cos(phi)*x0-sin(theta)*cos(phi)*y0+sin(phi)*z0;
distance= x0*a+y0*b+z0*c;		%This scalar projection plays the role of a distance.
    if (c1min<=coef1 & coef1<=c1max &    c2min<=coef2 & coef2<=c2max)
 	if distance > zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))
 			outpic(round(1+c2max-coef2),round(1+coef1-c1min),:)=inpic(i,j,:);
 		zbuffer(round(1+c2max-coef2),round(1+coef1-c1min))=distance;
	end
	end
%Orthographic projection routine ends here.
end
 end
%Finally, the output image is sent to the screen and 
%also saved to a file. Runtime is shorter if you
%do not send the image to the screen. Just put a "%" 
%in front of that line to disable it. On the other
%hand, you may want to view the image on the screen 
%but not save it to a file. In that case disable
%the imwrite line.
image(outpic/255); axis equal
imwrite(outpic/255,'outfile.jpg','jpg')