main.cc.html
//**************************************************************************
//
// CSE 486 Project #4
// By Anirudh Modi (anirudh@bart.aero.psu.edu) on 4/18/99-Sun
// & Jim Geis (geis@cse.psu.edu)
// & Howard Elikan (elikan@cse.psu.edu)
//
//**************************************************************************
// Have implemented the following ->
// 1. Image-Irradiance Equation
//**************************************************************************
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "image.h"
#include "matrix.h"
//**************************************************************************
#define FOCAL_LENGTH (5.0)
#define SPHERE_RADIUS (4.0)
#define BG_INTENSITY 64
#define IMAGE_DIM 256
#define XY_RANGE (1.0)
#define N_SAMPLE 512
//**************************************************************************
double ReflectanceSphere (double theta, double phi, double p_s, double q_s);
double Timer (void);
//**************************************************************************
int main (int argc, char *argv[])
{
if (argc != 4)
{
cerr << "Syntax: " << argv[0] << " <p_s> <q_s> <z0>" << endl;
exit(-1);
}
double p_s = atof(argv[1]);
double q_s = atof(argv[2]);
double z0 = atof(argv[3]);
double r = SPHERE_RADIUS;
double lambda = FOCAL_LENGTH;
double theta_i = asin(r/(z0-lambda));
double ri = lambda*r*cos(theta_i)/(z0-lambda-r*sin(theta_i));
if (ri > XY_RANGE)
{
double theta_i2 = acos(XY_RANGE/ri);
if (theta_i2 > theta_i)
theta_i = theta_i2;
}
Matrix T = TransformToImagePlane(0,0,0,0,0,1,0,0,0,lambda);
cout << "---------------------------------------"
<< "---------------------------------------" << endl;
cout << "Radius of sphere = " << r << endl;
cout << "Focal length of camera lens = " << lambda << endl;
cout << "Range of image plane = [" << -XY_RANGE << "," << XY_RANGE << "]x["
<< -XY_RANGE << "," << XY_RANGE << "]" << endl;
cout << "---------------------------------------"
<< "---------------------------------------" << endl;
cout << "p_s = " << p_s << endl;
cout << "q_s = " << q_s << endl;
cout << "z0 = " << z0 << endl;
double s_mag = sqrt(p_s*p_s+q_s*q_s+1.0);
printf("Direction of point source = [%g,%g,%g] = [%.3f,%.3f,%.3f]\n",
-p_s,-q_s,1.0,-p_s/s_mag,-q_s/s_mag,1.0/s_mag);
cout << "---------------------------------------"
<< "---------------------------------------" << endl;
if (z0 < (r+lambda))
{
cerr << "Fatal error: Part of sphere lies between the"
<< " lens and the image plane!" << endl;
cerr << "z0 should be >= " << r+lambda << endl;
exit(-1);
}
cout << "Radius of sphere on image plane = " << ri << endl;
Matrix w(4,1), c_h(4,1);
w.p[3][0] = 1.0;
int N_phi, N_theta;
if (ri < 1.0)
{
N_phi = (int) rint(N_SAMPLE*ri);
N_theta = (int) rint(N_SAMPLE*ri);
}
else
{
N_phi = N_SAMPLE;
N_theta = N_SAMPLE;
}
cout << "Number of points sampled for image plane = " << N_phi
<< "x" << N_theta << " = " << N_phi*N_theta << endl;
cout << endl;
int width = IMAGE_DIM;
int height = IMAGE_DIM;
GrayImage image(width, height, 255);
image.setValue(BG_INTENSITY);
int count;
double phi, theta, R, x, y, z, xi, yi;
int xx,yy,RR;
cout << "Generating shading information....." << endl;
double start_time = Timer();
fprintf(stderr, "%3d%% Completed",0);
for (int i = 0; i < N_phi; i++)
for (int j = 0; j < N_theta; j++)
{
phi = theta_i+(180.0*DEG2RAD-2*theta_i)*i/(N_phi-1);
theta = theta_i+(180.0*DEG2RAD-2*theta_i)*j/(N_theta-1);
R = ReflectanceSphere(theta, phi, p_s, q_s);
w.p[0][0] = x = - r * sin(theta) * cos(phi);;
w.p[1][0] = y = r * cos(theta);;
w.p[2][0] = z = z0 - r * sin(theta) * sin(phi);;
c_h = T * w;
if (fabs(c_h(3,0)) > 1.0e-4)
{
xi = c_h(0,0)/c_h(3,0);
yi = c_h(1,0)/c_h(3,0);
}
else
{
xi = 1.0e+10;
yi = 1.0e+10;
}
// PerspectiveTransform(T,x,y,z,&xi,&yi);
xx = (int) rint((xi+XY_RANGE)/(2*XY_RANGE)*(IMAGE_DIM-1));
yy = (int) rint((yi+XY_RANGE)/(2*XY_RANGE)*(IMAGE_DIM-1));
RR = (int) rint(R*255);
if (xx >= 0 && xx < IMAGE_DIM &&
yy >= 0 && yy < IMAGE_DIM &&
sqrt(xi*xi+yi*yi) < (ri-4.0/IMAGE_DIM))
image.p[yy][IMAGE_DIM-1-xx] = RR;
count = i*N_theta+j+1;
if (count%1000 == 0)
fprintf(stderr, "\r%3d%%",100*count/(N_theta*N_phi));
}
fprintf(stderr, "\r%3d%% Completed!\n",100);
double end_time = Timer();
fprintf(stderr,"Consumed %.1f seconds.\n",end_time-start_time);
cout << "---------------------------------------"
<< "---------------------------------------" << endl;
//image.reverseThreshold(255);
image.WriteToFile("/tmp/sphere.ppm");
cout << "---------------------------------------"
<< "---------------------------------------" << endl;
system("xv /tmp/sphere.ppm");
system("rm -f /tmp/sphere.ppm");
}
//**************************************************************************
double ReflectanceSphere (double theta, double phi, double p_s, double q_s)
{
double p = -cos(phi)*sin(theta);
double q = cos(theta);
double r = sin(phi)*sin(theta);
double R = (p*p_s+q*q_s+r)/sqrt(1.0+p_s*p_s+q_s*q_s);
if (R < 0.0)
R = 0.0;
return R;
}
//**************************************************************************
double Timer (void)
{
time_t time_now;
time(&time_now);
return (double) (time_now);
}
//**************************************************************************