1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
using namespace std;
string filename();
string filename2();
void readEGM(string fname, int &ncol, int &nrow, float &minel, float &maxel, float &hscale, float &vscale, float EGM[]); //reading in EGM function
float dot(float x, float y, float z, float x2, float y2, float z2); //dot product function
void cross(float x, float y, float z, float x2, float y2, float z2, float &i, float &j, float &k); //cross product function
void sun(float &azimuth, float &elevation); //prompting sun position function
void az2xyz(float azimuth, float elevation, float &x, float &y, float &z); //converting Azimuth and Elevation to x y z coordinates function
void normalize(float xin, float yin, float zin, float &x_norm, float &y_norm, float &z_norm); //normalizing vectors function
void illuminate(int ncol, int nrow, float EGM[], int PGM[], float azimuth, float elevation, float xscale, float yscale); //illuminating function
void writePGM(string fname2, int ncol, int nrow, int maxval, int PGM[]); //writing back PGM function
int main()
{
//declaring variables
float minel=0, maxel=0, hscale=0, vscale=0, xscale=0, yscale=0;
//float x_sun, y_sun, z_sun;
float azimuth=0, elevation=0;
float EGM[512 * 512]; //EGM array
int ncol = 0, nrow = 0;
int PGM[512 * 512]; //PGM array
int maxval = 255;
string fname = filename(); //filename declaration
string fname2 = filename2();
readEGM(fname, ncol, nrow, minel, maxel, hscale, vscale, EGM); //calling read EGM function
illuminate(ncol, nrow, EGM, PGM, azimuth, elevation, xscale, yscale); //calling illuminate function
writePGM(fname2, ncol, nrow, maxval, PGM);
return 0;
}
//function body for prompting input file of EGM
string filename()
{
string fname;
cout << "Please input filename of EGM: ";
cin >> fname;
return fname;
}
string filename2()
{
string fname2;
cout << "Please name file for PGM: ";
cin >> fname2;
return fname2;
}
//reading the EGM file function body
void readEGM(string fname, int &ncol, int &nrow, float &minel, float &maxel, float &hscale, float &vscale, float EGM[])
{
ifstream ifs;
string image_type;
ifs.open(fname);
ifs >> image_type >> ncol >> nrow >> minel >> maxel >> hscale >> vscale; //reading in header of EGM
if (image_type != "E1")
cout << "Can't handle the EGM, please try again" << endl; //if statement in case image type is not supported
for (int i = 0; i < nrow; i++) //nested for loop to read in EGM values to EGM array
{
for (int j = 0; j < ncol; j++)
{
int xy = i * ncol + j;
ifs >> EGM[xy];
}
}
}
//function body to prompt user for position of sun
void sun(float &azimuth, float &elevation)
{
cout << "Please input the position of sun in Azimuth and Elevation";
cin >> azimuth;
cin >> elevation;
}
//dot product function body
float dot(float x, float y, float z, float x2, float y2, float z2)
{
float result;
//calculating dot product
result = x * x2 + y * y2 + z * z2;
return result;
}
//cross product function body
void cross(float x, float y, float z, float x2, float y2, float z2, float &i, float &j, float &k)
{
//calculating and returning cross product
i = (y*z2) - (z*y2);
j = (z*x2) - (x*z2);
k = (x*y2) - (y*x2);
}
//converting azimuth and elevation to xyz coordinates
void az2xyz(float azimuth, float elevation, float &x, float &y, float &z)
{
//converting azimuth and elevation to xyz coordinates
x = cos(elevation) * cos(azimuth);
y = cos(elevation) * sin(azimuth);
z = sin(elevation);
}
//normalizing vector function body
void normalize(float xin, float yin, float zin, float &x_norm, float &y_norm, float &z_norm)
{
float unitvec;
unitvec = sqrt((xin*xin) + (yin*yin) + (zin * zin));
x_norm = xin / unitvec;
y_norm = yin / unitvec;
z_norm = zin / unitvec;
}
//illuminate function body
void illuminate(int ncol, int nrow, float EGM[], int PGM[], float azimuth, float elevation, float xscale, float yscale)
{
//declaring variables
int r, c;
float x, y, z, x_norm, y_norm, z_norm;
float Az[512 * 512], Bz[512 * 512];
float i, j, k;
float inorm, jnorm, knorm;
sun(azimuth, elevation); //prompts for input of sun's position
az2xyz(azimuth, elevation, x, y, z); //converts Azi and Ele to x y z coordinates
normalize(x, y, z, x_norm, y_norm, z_norm); //normalizes x y z coordinates
for (r = 0; r < ncol - 1; r++)
{
for (c = 0; c < nrow - 1; c++)
{
int index = (r*ncol) + (c + 1); //declaring array index
int index2 = (r + 1) * (ncol + c);
Az[index] = EGM[index + 1] - EGM[index];
Bz[index2] = EGM[index2] - EGM[index];
cross(xscale, 0, Az[index], 0, yscale, Bz[index2], i, j, k); //calling cross product function
normalize(i, j, k, inorm, jnorm, knorm); //calling normalize function
PGM[index] = (dot(inorm, jnorm, knorm, x_norm, y_norm, z_norm)) * 255;
cout << PGM[c] << " ";
}
}
}
void writePGM(string fname2, int ncol, int nrow, int maxval, int PGM[])
{
ofstream ofs(fname2);
ofs.open(fname2);
ofs << "P2" << " " << ncol << " " << nrow << " " << maxval << endl;
for (int i = 0; i < nrow; i++)
{
for (int j = 0; j < ncol; j++)
{
int xy = i * ncol + j;
ofs << PGM[xy];
}
}
}
|