%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')