1 /* -*- Mode: C++ -*- *****************************************************
3 * Written by Durk Talsma, around 1995/1996.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **************************************************************************/
21 /********************************************************************
22 * This file defines a simple Vector and Matrix library. These were
23 * originally written for my (yet) unpublished planetarium / solar
24 * system simulator program. The are included here, because I have
25 * experience the code to calculate angles between vectors. I'm sure
26 * similar functions exist already somewhere else so I don't mind
27 * whether this gets eventually replaced by something more suitable
28 * The functions are based on a description in Tyler. A. (1994). C++
29 * Real-time 3D graphics. Sigma press, Wilmslow, England.
31 * The original versions were written under windows, hence the occasional
32 *::MessageBox() statements between conditional compile statements
34 ********************************************************************/
40 const double PiOver180 = 1.74532925199433E-002;
41 const double Pix4dif3 = 4.1887902;
43 Vector::Vector(int size)
46 for (int i = 0; i < nrData; i++)
50 double Vector::VecLen()
54 for (int i= 0; i < nrData; i++)
55 length += pow(data[i],2);
60 double VecDot(Vector first, Vector second)
63 result = ((first.xVal*second.xVal) +
64 (first.yVal*second.yVal) +
65 (first.zVal*second.zVal));
69 for (int i = 0; i < first.nrData; i++)
70 result += first.data[i] * second.data[i];
75 Vector VecCross(Vector first, Vector second)
78 /*return Vec3 ( (first.yVal*second.zVal - first.zVal*second.yVal),
79 (first.zVal*second.xVal - first.zVal*second.xVal),
80 (first.xVal*second.yVal - first.yVal*second.xVal) );
83 if ( (first.nrData != 4) || (first.nrData != second.nrData) )
85 ::MessageBox(0, "Attempting to calculate Cross product with 2\n"
86 "unequally sized vectors in\n"
87 "Vector VecCross(Vector, Vector", "Error",
93 double x = first.data[1] * second.data[2] - first.data[2]*second.data[1];
94 double y = first.data[2] * second.data[0] - first.data[0]*second.data[2];
95 double z = first.data[0] * second.data[1] - first.data[1]*second.data[0];
103 Vector operator- (Vector first, Vector second)
105 /*return Vec3( first.xVal - second.xVal,
106 first.yVal - second.yVal,
107 first.zVal - second.zVal );
110 if ( first.nrData != second.nrData )
112 ::MessageBox(0, "Attempting to subtract 2 \n"
113 "unequally sized vectors in\n"
114 "Vector operator-(Vector, Vector", "Error",
120 double *temp = new double[first.nrData];
121 for (int i = 0; i < first.nrData; i++)
122 temp[i] = first.data[i] - second.data[i];
123 Vector result(first.nrData, temp);
129 Vector operator+ (Vector first, Vector second)
131 /*return Vec3( first.xVal + second.xVal,
132 first.yVal + second.yVal,
133 first.zVal + second.zVal );
136 if ( first.nrData != second.nrData )
138 ::MessageBox(0, "Attempting to add 2\n"
139 "unequally sized vectors in\n"
140 "Vector operator+(Vector, Vector", "Error",
145 double *temp = new double[first.nrData];
146 for (int i = 0; i < first.nrData; i++)
147 temp[i] = first.data[i] + second.data[i];
148 Vector result(first.nrData, temp);
153 Vector Vector::operator +=(Vector other)
156 if ( first.nrData != second.nrData )
158 ::MessageBox(0, "Attempting to add 2\n"
159 "unequally sized vectors in\n"
160 "Vector operator+(Vector, Vector", "Error",
165 for (int i = 0; i < nrData; i++)
166 data[i] += other.data[i];
170 Vector Vector::operator -=(Vector other)
173 if ( first.nrData != second.nrData )
175 ::MessageBox(0, "Attempting to add 2\n"
176 "unequally sized vectors in\n"
177 "Vector operator+(Vector, Vector", "Error",
182 for (int i = 0; i < nrData; i++)
183 data[i] -= other.data[i];
191 Vector operator* (Matrix mx, Vector vc)
194 sizes[0] = vc.nrData;
196 sizes[2] = mx.columns;
199 if ( (sizes[0] != sizes[1]) || (sizes[0] != sizes[2]) )
202 sprintf(buffer, "Sizes don't match in function\n"
203 "Vector operator*(Matrix, Vector)\n"
204 "sizes are: %d, %d, %d", sizes[0], sizes[1],sizes[2]);
205 MessageBox(0, buffer, "Error", MB_OK | MB_ICONEXCLAMATION);
209 double* result = new double[sizes[0]];
212 for (col = 0; col < sizes[0]; col++)
215 for (row = 0; row < sizes[0]; row++)
216 result[col] += vc[row] * mx[row][col];
218 Vector res(4, result);
223 sprintf(buffer, "return value of vector * matrix multiplication is\n"
224 "(%f, %f, %f, %f) ", result[0], result[1], result[2], result[3]);
225 ::MessageBox(0, buffer, "Information", MB_OK);
232 Vector operator*(Vector v1, Vector v2)
234 int size1 = v1.nrData;
238 int size2 = v2.nrData;
241 ::MessageBox(0, "Vector sizes don't match in Vector operator*(Vector, Vector)",
246 double *tempRes = new double[size1];
247 for (int i= 0; i < size1; i++)
248 tempRes[i] = v1[i] * v2[i];
249 Vector result(size1, tempRes);
255 Vector operator*(Vector vec, double d)
257 double* tempRes = new double[vec.nrData];
258 for (int i = 0; i < vec.nrData; i++)
259 tempRes[i] = vec[i] * d;
260 Vector result(vec.nrData, tempRes);
265 Vector operator/(Vector vec, double d)
267 double* tempRes = new double[vec.nrData];
268 for (int i = 0; i < vec.nrData; i++)
269 tempRes[i] = vec[i] / d;
270 Vector result(vec.nrData, tempRes);
275 ostream& operator << (ostream& os, Vector& vec)
277 os << /*setw(4) << */vec.nrData << '\t';
278 for (int i = 0; i < vec.nrData; i++)
279 os /*<< setw(25) */<< vec[i] << '\t';
283 istream& operator >> (istream& is, Vector& vec)
288 vec.data = new double[vec.nrData];
289 for (int i = 0; i < vec.nrData; i++)
294 ostream& Vector::binSave(ostream& os)
296 os.write((char*) &nrData, sizeof(int));
297 os.write((char*) data, nrData* sizeof(double));
306 /******************************************************************************
307 Matrix manipulation routines
308 ******************************************************************************/
310 Matrix::Matrix(int r, int c, double*dta)
313 for (int i = 0; i < rows; i++)
314 for (int j = 0; j < columns; j++)
315 data[i][j] = (*dta++);
318 Matrix::Matrix(int r, int c, double** dta)
321 for (int i = 0; i < rows; i++)
322 for (int j = 0; j < columns; j++)
323 data[i][j] = dta[i][j];
326 Matrix::Matrix(int r, int c, Vector* dta)
329 for (int i = 0; i < rows; i++)
333 Matrix::Matrix(Matrix& other)
335 build (other.rows, other.columns);
336 for (int i = 0; i< rows; i++)
337 (*this)[i] = other[i];
340 void Matrix::build(int row, int col)
345 data = new Vector [rows];
346 for (int i = 0; i < rows; i++)
350 Matrix& Matrix::operator =(Matrix& other)
353 columns = other.columns;
354 for (int i = 0; i < rows; i++)
355 (*this)[i] = other[i];
360 Vector Matrix::operator ()(int col)
363 for (int i = 0; i < rows; i++)
364 Col[i] = data[i][col];
368 void Matrix::norm(int scale)
370 for (int i = 0; i < rows; i++)
371 for (int j = 0; j < columns; j++)