//*************************************************************************** #include <iostream.h> #include <fstream.h> #include <stdlib.h> /* ANSI C standard library routines */ #include <string.h> /* ANSI standard string routines */ #include <limits.h> #include <math.h> #include <stdio.h> #include "image.h" #include "matrix.h" //*************************************************************************** Matrix::Matrix ( ) // Constructor { allocateFlag = 0; Optimization2D = 0; } //*************************************************************************** Matrix::Matrix (int m, int n) // Constructor { Init (m, n); } //*************************************************************************** Matrix::~Matrix ( ) // Destructor { deAllocateMem( ); } //*************************************************************************** void Matrix::Init (int m, int n) // Called by Constructor { allocateFlag = 0; Optimization2D = 0; nx = m; ny = n; allocateMem (nx, ny); } //*************************************************************************** void Matrix::allocateMem (int m, int n) { if (allocateFlag) { cerr << "Matrix::allocateMem: Memory already allocated!!" << endl; return; } allocateFlag = 1; p = new float *[m]; for (int i = 0; i < m; i++) { p[i] = new float [n]; if (!p[i]) { cerr << "Matrix: Not enough memory for allocateMem!!" << endl; exit(-1); } for (int j = 0; j < n; j++) p[i][j] = 0.0; } } //*************************************************************************** void Matrix::deAllocateMem ( ) { if (!allocateFlag) return; for (int i = 0; i < nx; i++) delete p[i]; delete p; allocateFlag = 0; } //*************************************************************************** void Matrix::Identity () { if (nx != ny) { cerr << "Identity(): Nx not equal to Ny !!" << endl; exit(-1); } for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) p[i][j] = 0.0; p[i][i] = 1.0; } } //*************************************************************************** void Matrix::translate (float x, float y, float z) { *this = *this * Translate(x,y,z); } //*************************************************************************** void Matrix::scale (float x, float y, float z) { *this = *this * Scale(x,y,z); } //*************************************************************************** void Matrix::rotate (float angle, float x, float y, float z) { *this = *this * Rotate(angle,x,y,z); } //*************************************************************************** Matrix &Matrix::Transpose () { static Matrix *M = new Matrix(ny,nx); for (int i = 0; i < ny; i++) for (int j = 0; j < nx; j++) M->p[i][j] = p[j][i]; return *M; } //*************************************************************************** int Matrix::operator== (Matrix &M) { if (M.nx != nx || M.ny != ny) { cerr << "operator ==: Both matrices are not of the same size!!" << endl; exit(-1); } for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) if (p[i][j] != M.p[i][j]) return 0; return 1; } //*************************************************************************** void Matrix::operator+= (Matrix &M) { if (M.nx != nx || M.ny != ny) { cerr << "operator +=: Both matrices are not of the same size!!" << endl; exit(-1); } for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] += M.p[i][j]; } //*************************************************************************** Matrix &Matrix::operator= (const Matrix &M) { if (this == &M) return *this; nx = M.nx; ny = M.ny; if (!allocateFlag) allocateMem (nx, ny); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] = M.p[i][j]; return *this; } //*************************************************************************** Matrix &Matrix::operator+ (Matrix &M1) { static Matrix *M = new Matrix; if (M1.nx != nx || M1.ny != ny) { cerr << "operator +: Both matrices are not of the same size!!" << endl; exit(-1); } *M = M1; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j] + M1.p[i][j]; return *M; } //*************************************************************************** Matrix &Matrix::operator- (Matrix &M1) { static Matrix *M = new Matrix; if (M1.nx != nx || M1.ny != ny) { cerr << "operator -: Both matrices are not of the same size!!" << endl; exit(-1); } *M = M1; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j] - M1.p[i][j]; return *M; } //*************************************************************************** // Pixel by pixel multiplication Matrix &Matrix::operator^ (Matrix &M1) { static Matrix *M = new Matrix; if (M1.nx != nx || M1.ny != ny) { cerr << "operator ^: Both matrices are not of the same size!!" << endl; exit(-1); } *M = M1; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j] * M1.p[i][j]; return *M; } //*************************************************************************** // Pixel by pixel division Matrix &Matrix::operator/ (Matrix &M1) { static Matrix *M = new Matrix; if (M1.nx != nx || M1.ny != ny) { cerr << "operator /: Both matrices are not of the same size!!" << endl; exit(-1); } *M = M1; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j] / M1.p[i][j]; return *M; } //*************************************************************************** Matrix &Matrix::operator* (float k) { static Matrix *M = new Matrix(nx,ny); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j]*k; return *M; } //*************************************************************************** Matrix &Matrix::operator/ (float k) { static Matrix *M = new Matrix(nx,ny); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) M->p[i][j] = p[i][j]/k; return *M; } //*************************************************************************** Matrix &Matrix::operator* (Matrix &M1) { if (ny != M1.nx) { cerr << "operator *: Cannot multiply " << nx << "x" << ny << " matrix by " << M1.nx << "x" << M1.ny << " matrix!!" << endl; exit(-1); } static int mx = nx, my = M1.ny; static Matrix *M = new Matrix(mx,my); if (mx != nx || my != M1.ny) { mx = nx; my = M1.ny; delete M; M = new Matrix(mx,my); } for (int i = 0; i < M->nx; i++) for (int j = 0; j < M->ny; j++) { M->p[i][j] = 0.0; for (int k = 0; k < M1.nx; k++) M->p[i][j] += p[i][k]*M1.p[k][j]; } return *M; } //*************************************************************************** ostream &operator<< (ostream &Out, Matrix &M) { for (int i = 0; i < M.nx; i++) { for (int j = 0; j < M.ny; j++) { Out.setf(ios::fixed,ios::floatfield); Out.precision(4); if (M.p[i][j] >= 0.0) Out << " "; Out << M.p[i][j] << " "; } Out << endl; } Out << endl; Out.precision(6); Out.setf(0,ios::floatfield); return Out; } //*************************************************************************** float Matrix::operator() (int i, int j) { return p[i][j]; } //*************************************************************************** float *Matrix::arrayform() { float *a = new float [nx*ny]; float *b; for (int j = 0; j < ny; j++) for (int i = 0; i < nx; i++) { a[j*nx+i] = p[i][j]; } b = a; return b; } //*************************************************************************** Matrix &Transpose (Matrix &M) { return M.Transpose(); } //*************************************************************************** Matrix &Identity (int n) { static Matrix *M = new Matrix(n,n); M->Identity(); return *M; } //*************************************************************************** Matrix &Rotate (float angle, float x, float y, float z) { float r = sqrt(x*x+y*y+z*z); if (fabs(r-1.0) > 1.0e-6) { x = x/r; y = x/r; z = x/r; } float c = cos(angle); float s = sin(angle); static Matrix *M = new Matrix(4,4); M->p[0][0] = x*x*(1.0-c)+c; M->p[0][1] = x*y*(1.0-c)-z*s; M->p[0][2] = x*z*(1.0-c)+y*s; M->p[0][3] = 0.0; M->p[1][0] = y*x*(1.0-c)+z*s; M->p[1][1] = y*y*(1.0-c)+c; M->p[1][2] = y*z*(1.0-c)-x*s; M->p[1][3] = 0.0; M->p[2][0] = z*x*(1.0-c)-y*s; M->p[2][1] = z*y*(1.0-c)+x*s; M->p[2][2] = z*z*(1.0-c)+c; M->p[2][3] = 0.0; M->p[3][0] = 0.0; M->p[3][1] = 0.0; M->p[3][2] = 0.0; M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &xRotate (float angle) { static Matrix *M = new Matrix(4,4); M->p[1][1] = M->p[2][2] = cos(angle); M->p[1][2] = sin(angle); M->p[2][1] = -sin(angle); M->p[0][0] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &yRotate (float angle) { static Matrix *M = new Matrix(4,4); M->p[0][0] = M->p[2][2] = cos(angle); M->p[0][2] = sin(angle); M->p[2][0] = -sin(angle); M->p[1][1] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &zRotate (float angle) { static Matrix *M = new Matrix(4,4); M->p[0][0] = M->p[1][1] = cos(angle); M->p[0][1] = sin(angle); M->p[1][0] = -sin(angle); M->p[2][2] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &Translate (float x, float y, float z) { static Matrix *M = new Matrix(4,4); M->p[0][3] = x; M->p[1][3] = y; M->p[2][3] = z; M->p[0][0] = M->p[1][1] = M->p[2][2] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &Scale (float x, float y, float z) { static Matrix *M = new Matrix(4,4); M->p[0][0] = x; M->p[1][1] = y; M->p[2][2] = z; M->p[0][0] = M->p[1][1] = M->p[2][2] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &Perspective (float lambda) { static Matrix *M = new Matrix(4,4); M->p[3][2] = -1.0/lambda; M->p[0][0] = M->p[1][1] = M->p[2][2] = M->p[3][3] = 1.0; return *M; } //*************************************************************************** Matrix &TransformToImagePlane (float x0, float y0, float z0, float xC, float yC, float zC, float r1, float r2, float r3, float lambda) { static Matrix *M = new Matrix; float x = xC - x0; float y = yC - y0; float z = zC - z0; float r = sqrt(x*x+y*y+z*z); float theta = atan2(x,-y); float alpha = acos(z/r); if (x == 0.0 && y == 0.0) // bugfix for Linux egcs-c++ atan2(,) function theta = 0.0; Matrix P = Perspective(lambda); Matrix Tw0 = Translate(-x0,-y0,-z0); Matrix R_theta = zRotate(theta); Matrix R_alpha = xRotate(alpha); Matrix Tr = Translate(-r1,-r2,-r3); Matrix T = P * Tr * R_alpha * R_theta * Tw0; //cout << "alpha = " << alpha/DEG2RAD << " deg" << endl; //cout << "theta = " << theta/DEG2RAD << " deg" << endl; *M = T; return *M; } //*************************************************************************** void PerspectiveTransform (Matrix T, float x, float y, float z, float *xp, float *yp) { Matrix w(4,1), c_h(4,1); w.p[0][0] = x; w.p[1][0] = y; w.p[2][0] = z; w.p[3][0] = 1.0; c_h = T * w; if (fabs(c_h(3,0)) > 1.0e-4) { *xp = c_h(0,0)/c_h(3,0); *yp = c_h(1,0)/c_h(3,0); } else { *xp = 1.0e+10; *yp = 1.0e+10; } } //*************************************************************************** void Matrix::translate_and_rotate2D (float x, float y, float angle) { p[0][0] = p[1][1] = cos(angle); p[1][0] = sin(angle); p[0][1] = -p[1][0]; p[0][2] = x; p[1][2] = y; } //*************************************************************************** void Matrix::transformXY (int x, int y, int *xf, int *yf) { if (Optimization2D) { *xf = (int) (x*p[0][0] + y*p[0][1] + p[0][3]); *yf = (int) (x*p[1][0] + y*p[1][1] + p[1][3]); } else { Matrix w(4,1), v(4,1); w.p[0][0] = x; w.p[1][0] = y; w.p[2][0] = 0.0; w.p[3][0] = 1.0; v = *this * w; *xf = (int) (v(0,0)/v(3,0)); *yf = (int) (v(1,0)/v(3,0)); } } //*************************************************************************** // Or and Oi are changed void MatrixFFT2D(Matrix *Or, Matrix *Oi, Matrix *Ir, Matrix *Ii) { MatrixFFT2D(Or, Oi, Ir, Ii, 1); } //*************************************************************************** // Or and Oi are changed void MatrixIFFT2D(Matrix *Or, Matrix *Oi, Matrix *Ir, Matrix *Ii) { MatrixFFT2D(Or, Oi, Ir, Ii, -1); } //*************************************************************************** static void four1(float *data, int nn, int isign); //*************************************************************************** // 2D Fourier Transform of data with real part stored in Ir // and imaginary part in Ii. // isign = 1 => Forward FFT; isign = -1 => Inverse FFT // Or and Oi are changed void MatrixFFT2D(Matrix *Or, Matrix *Oi, Matrix *Ir, Matrix *Ii, int isign) { int nx = Ir->nx; int ny = Ir->ny; Matrix T(2*nx,ny); float *tmp1 = new float [2*ny+1]; float *tmp2 = new float [2*nx+1]; for (int i = 1; i <= nx; i++) { for (int j = 1; j <= ny; j++) { tmp1[j*2-1] = Ir->p[i-1][j-1]; tmp1[j*2] = Ii->p[i-1][j-1]; } four1(tmp1, ny, isign); for (int j = 1; j <= ny; j++) { T.p[i*2-2][j-1] = tmp1[j*2-1]; T.p[i*2-1][j-1] = tmp1[j*2]; } } for (int i = 1; i <= ny; i++) { for (int j = 1; j <= nx; j++) { tmp2[j*2-1] = T.p[j*2-2][i-1]; tmp2[j*2] = T.p[j*2-1][i-1]; } four1(tmp2,nx,isign); for (int j = 1; j <= nx; j++) { Or->p[j-1][i-1] = tmp2[j*2-1]; Oi->p[j-1][i-1] = tmp2[j*2]; } } delete tmp1; delete tmp2; } //*************************************************************************** // From NRC static void four1(float *data, int nn, int isign) { float wtemp, wr, wpr, wpi, wi, theta; float tempr; #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr int n = nn << 1; int j = 1; for (int i = 1; i < n; i += 2) { if (j > i) { SWAP(data[j],data[i]); SWAP(data[j+1],data[i+1]); } int m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } int mmax = 2; while (n > mmax) { int istep = 2*mmax; theta = 2*Pi/(isign*mmax); wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0; wi = 0.0; for (int m = 1; m < mmax; m += 2) { for (int i = m; i <= n; i += istep) { j = i+mmax; tempr = wr*data[j]-wi*data[j+1]; float tempi = wr*data[j+1]+wi*data[j]; data[j] = data[i]-tempr; data[j+1] = data[i+1]-tempi; data[i] += tempr; data[i+1] += tempi; } wr = (wtemp=wr)*wpr-wi*wpi+wr; wi = wi*wpr+wtemp*wpi+wi; } mmax = istep; } #undef SWAP } //*************************************************************************** // Pixel by Pixel product A = B * C // A is changed, B and C are not void MatProduct(Matrix *A, Matrix *B, Matrix *C) { for (int h = 0; h < A->nx; h++) for (int w = 0; w < A->ny; w++) A->p[h][w] = B->p[h][w] * C->p[h][w]; } //*************************************************************************** // Pixel by Pixel product A = B + C // A is changed, B and C are not void MatSum(Matrix *A, Matrix *B, Matrix *C) { for (int h = 0; h < A->nx; h++) for (int w = 0; w < A->ny; w++) A->p[h][w] = B->p[h][w] + C->p[h][w]; } //*************************************************************************** // Pixel by Pixel product A = B - C // A is changed, B and C are not void MatDiff(Matrix *A, Matrix *B, Matrix *C) { for (int h = 0; h < A->nx; h++) for (int w = 0; w < A->ny; w++) A->p[h][w] = B->p[h][w] - C->p[h][w]; } //*************************************************************************** // v is changed, m is not void Matrix2Vector(Matrix *m, float *v) { int nh = m->nx; int nw = m->ny; for (int h = 0; h < nh; h++) for (int w = 0; w < nw; w++) v[h*nw+w] = (float) m->p[h][w]; } //*************************************************************************** void MatCopy(Matrix *A, Matrix *B, int h_target, int w_target, int h_begin, int w_begin, int h_end, int w_end) { int Anx = A->nx, Any = A->ny; int Bnx = B->nx, Bny = B->ny; if ((h_target >= 0) && (h_target < Anx) && (w_target >= 0) && (w_target < Any)) { if ((h_begin >= 0) && (h_begin < Bnx) && (w_begin >= 0) && (w_begin < Bny)) { int h = h_end-h_begin+1; int w = w_end-w_begin+1; if ((h >= 1) && (w >= 1)) { int h_done = h_target+h-1; int w_done = w_target+w-1; if ((h_done < Anx) && (w_done < Any)) { for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { A->p[i+h_target][j+w_target] = B->p[i+h_begin][j+w_begin]; } } } } } } else { cerr << "MatCopy: Matrix dimension error (Source matrix is " << A->nx << "x" << A->ny << ", Dest matrix is " << B->nx << "x" << B->ny << ")!" << endl; cerr << "\tParameters are (" << h_target << "," << w_target << "," << h_begin << "," << w_begin << "," << h_end << "," << w_end << ")" << endl; exit(-1); } } //*************************************************************************** float log2(double x) { return log10(x)/log10(2.0); } //*************************************************************************** void Matrix::WriteImage(char *filename, char *fmt) { GrayImage img; img.ReadFromMatrix(*this); img.WriteToFile(filename, fmt); } //*************************************************************************** void Matrix::WriteImage(char *filename) { GrayImage img; img.ReadFromMatrix(*this); img.WriteToFile(filename); } //*************************************************************************** void Matrix::WriteFFTImage(char *filename, char *fmt) { GrayImage img; Matrix tmp(nx, ny); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) tmp.p[i][j] = log10(1.0+fabs(p[i][j])); img.ReadFromMatrix(tmp); img.WriteToFile(filename, fmt); } //*************************************************************************** void Matrix::WriteFFTImage(char *filename) { GrayImage img; Matrix tmp(nx, ny); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) tmp.p[i][j] = log10(1.0+fabs(p[i][j])); img.ReadFromMatrix(tmp); img.WriteToFile(filename); } //*************************************************************************** void Matrix::Abs() { for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] = fabs(p[i][j]); } //*************************************************************************** // Real is replaced by Magnitude, Imag is replaced by Phase void Complex2Polar(Matrix *Real, Matrix *Imag) { int nx = Real->nx; int ny = Real->ny; if (nx != Imag->nx || ny != Imag->ny) { cerr << "Magnitude: Dimensions of the input and output matrices" << " do not match!!" << endl; } for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) { double magnitude = sqrt(Real->p[i][j]*Real->p[i][j] + Imag->p[i][j]*Imag->p[i][j]); double phase = atan2(Imag->p[i][j], Real->p[i][j]); Real->p[i][j] = magnitude; Imag->p[i][j] = phase; } /* // Do phase unwrapping to remove discontinuities at +Pi/-Pi. #define TOL 1.0e-3 for (int i = 1; i < nx; i++) for (int j = 0; j < ny; j++) { if (fabs((Imag->p[i][j]-Imag->p[i-1][j]) - TwoPi) < TOL) Imag->p[i-1][j] += TwoPi; } */ } //*************************************************************************** float Matrix::Norm() { double norm = 0.0; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) norm += p[i][j]*p[i][j]; norm = sqrt(norm); return (float) norm; } //*************************************************************************** // Normalize between 0 to 1 void Matrix::Normalize() { double minp = 1.0e+300, maxp = -1.0e+300; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) { if (p[i][j] > maxp) maxp = p[i][j]; if (p[i][j] < minp) minp = p[i][j]; } double range = maxp-minp; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] = (p[i][j]-minp)/range; } //*************************************************************************** // Normalize based on enery (norm2) void Matrix::NormalizeEnergy() { float energy = 0.0; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) energy += fabs(p[i][j]); //cout << "Energy factor = " << energy << endl; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] /= energy; } //*************************************************************************** // Normalize based on enery (norm) void Matrix::Normalize2() { double norm = 0.0; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) norm += fabs(p[i][j]); norm = sqrt(norm); //cout << "Normalization factor = " << norm << endl; for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] /= (float) norm; } //*************************************************************************** void Matrix::scale(float k) { for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] *= k; } //*************************************************************************** void Matrix::Zero() { for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) p[i][j] = 0.0; } //*************************************************************************** void Matrix::Threshold(float k) { for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) { if (p[i][j] > k) p[i][j] = 1.0; else p[i][j] = 0.0; } } //*************************************************************************** Matrix *allocateMatrixArray(int n, int height, int width) { Matrix *M; M = new Matrix [n]; for (int i = 0; i < n; i++) { M[i].Init(height, width); } return M; } //************************************************************************** void deallocateMatrixArray(Matrix *M, int n) { for (int i = 0; i < n; i++) { M[i].deAllocateMem(); } delete M; } //************************************************************************** void printMatrixArray(Matrix *M, char *filename, int n, int height, int width) { Matrix Big(n*height, width); for (int i = 0; i < n; i++) MatCopy(&Big, &M[i], i*height, 0, 0, 0, height-1, width-1); Big.WriteImage(filename, "gif"); } //************************************************************************** Matrix **allocateMatrixArray(int nx, int ny, int height, int width) { Matrix **M; M = new Matrix *[nx]; for (int i = 0; i < nx; i++) { M[i] = new Matrix [ny]; for (int j = 0; j < ny; j++) M[i][j].Init(height, width); } return M; } //************************************************************************** void deallocateMatrixArray(Matrix **M, int nx, int ny) { for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) { M[i][j].deAllocateMem(); } delete M[i]; } delete M; } //************************************************************************** void printMatrixArray(Matrix **M, char *filename, int nx, int ny, int height, int width) { Matrix Big(nx*height, ny*width); for (int i = 0; i < nx; i++) for (int j = 0; j < ny; j++) MatCopy(&Big, &M[i][j], i*height, j*width, 0, 0, height-1, width-1); Big.WriteImage(filename, "gif"); } //************************************************************************** int Matrix::WriteToFile(char *FileName) { ofstream out(FileName); if (!out) return -1; // Invalid Filename cout << "Writing " << nx << "x" << ny << " matrix to file \"" << FileName << "\"..."; out << nx << " " << ny << endl; for (int i = 0; i < nx; i++) out.write((char *) p[i], sizeof(float)*ny); out.close(); cout << "done!" << endl; return 0; // No error encountered....successful completion } //*************************************************************************** int Matrix::ReadFromFile(char *FileName) { const int buf_size = 40; char buf[buf_size]; ifstream inp(FileName); if (!inp) // Invalid FileName { cerr << "Matrix::ReadFromFile: Invalid filname: \"" << FileName << "\" does not exist!!" << endl; exit(-1); } inp.getline(buf,buf_size); while (buf[0] == '#') // ignore comments inp.getline(buf,buf_size); nx = atoi(buf); ny = atoi(strpbrk(buf, " \t")); cout << "Reading " << nx << "x" << ny << " matrix from file \"" << FileName << "\"..."; if (!allocateFlag) allocateMem(nx, ny); for (int i = 0; i < nx; i++) inp.read((char *) p[i], sizeof(float)*ny); cout << "done!" << endl; return 0; // No error encountered....successful completion } //*************************************************************************** void Write2DTecplotFile(Matrix *R, Matrix *I, char *filename) { ofstream out(filename); cout << "Writing two " << R->nx << "x" << R->ny << " matrices to a 2D TECPLOT file \"" << filename << "\"..."; int height = R->nx; int width = R->ny; out << "Title = \"Anirudh's Image Library\"" << endl; out << "Variables = \"X\", \"Y\", \"Ex\", \"Ey\"" << endl; out << "zone i = " << height << " j = " << width << endl; for (int j = 0; j < width; j++) { for (int i = 0; i < height; i++) { out << i << " " << j << " " << R->p[i][j] << " " << I->p[i][j] << endl; } out << endl; } out.close(); cout << "done!" << endl; } //*************************************************************************** int Matrix::isBoundaryPixel(int x, int y) { if (p[x][y] == 0.0) return 0; int count = 0; for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) { int xn = x + i; int yn = y + j; if (xn >= 0 && xn < nx && yn >=0 && yn < ny && !(xn == x && yn == y) && p[xn][yn]) ++count; } if (count == 1) return 1; else return 0; } //***************************************************************************