/* -*- Mode: C++ -*- ***************************************************** * mymath.h * Written by Durk Talsma, around 1995/1996. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * **************************************************************************/ /******************************************************************** * This file defines a simple Vector and Matrix library. These were * originally written for my (yet) unpublished planetarium / solar * system simulator program. The are included here, because I have * experience the code to calculate angles between vectors. I'm sure * similar functions exist already somewhere else so I don't mind * whether this gets eventually replaced by something more suitable * The functions are based on a description in Tyler. A. (1994). C++ * Real-time 3D graphics. Sigma press, Wilmslow, England. * * The original versions were written under windows, hence the occasional *::MessageBox() statements between conditional compile statements * ********************************************************************/ #ifndef _MY_MATH_H_ #define _MY_MATH_H__ #include <math.h> #include <fstream> #include <iomanip> using namespace std; #include <fg_constants.h> extern const double PiOver180; extern const double Pix4dif3; class Matrix; class Vector { private: int nrData; double* data; public: Vector(); Vector(int size); Vector(int size, double* dta); Vector(double x, double y, double z); Vector(Vector& other); Vector(istream& is); ~Vector(); void SetVal(double x, double y, double z); void build(int); Vector* GetVector(); double GetX(); double GetY(); double GetZ(); void AddX(double x); void AddY(double y); void AddZ(double z); void SubtractX(double x); void SubtractY(double y); void SubtractZ(double z); double VecLen(); Vector& operator = (Vector&); double& operator[] (int); int getDim(); ostream& binSave(ostream& os); Vector operator +=(Vector other); Vector operator -=(Vector other); friend double VecDot(Vector first, Vector second); friend Vector VecCross(Vector first, Vector second); friend Vector operator-(Vector first, Vector second); friend Vector operator+(Vector first, Vector second); friend Vector operator*(Matrix mx, Vector vc); friend Vector operator*(Vector v1, Vector v2); friend Vector operator*(Vector vec, double d); friend Vector operator/(Vector vec, double d); friend ostream& operator << (ostream& os, Vector& vec); friend istream& operator >> (istream& is, Vector& vec); }; /*----------------------------------------------------------------------------- nonmember friend functions ------------------------------------------------------------------------------*/ double VecDot(Vector first, Vector second); Vector VecCross(Vector first, Vector second); Vector operator-(Vector first, Vector second); Vector operator+(Vector first, Vector second); Vector operator*(Matrix mx, Vector vc); Vector operator*(Vector v1, Vector v2); Vector operator*(Vector vec, double d); Vector operator/(Vector vec, double d); ostream& operator << (ostream& os, Vector& vec); istream& operator >> (istream& is, Vector& vec); /*------------------------------------------------------------------------------ inline member functions ------------------------------------------------------------------------------*/ inline Vector::Vector() { nrData = 0; data = 0; } inline void Vector::build(int size) { nrData = size; data = new double[nrData]; #ifdef DEBUG if (!data) { ::MessageBox(0, "Error Allocating Memory for a new Vector", "Error", MB_OK); exit(1); } #endif //for (int i = 0; i < nrData; i++) // data[i] = 0.00; } inline Vector::Vector(int size, double* dta) { build(size); memcpy(data, dta, nrData*sizeof(double)); } inline Vector::Vector(Vector& other) { build(other.nrData); memcpy(data,other.data,nrData*sizeof(double)); } inline Vector::Vector(double x, double y, double z) { build(4); // one extra for matrix multiplication... data[0] = x; data[1] = y; data[2] = z; data[3] = 0.00; } inline Vector::Vector(istream& is) { is.read((char*) &nrData, sizeof(int)); data = new double[nrData]; is.read((char*) data, nrData * sizeof(double)); } inline Vector::~Vector() { delete [] data; } inline void Vector::SetVal(double x, double y, double z) { #ifdef DEBUG if (nrData != 4) { ::MessageBox(0, "Attempt to assign data to a vector\n" "With size unequal to 4 in function\n" " Vector::Setval(double, double, double", "Error" , MB_OK); exit(1); } #endif data[0] = x, data[1] = y; data[2] = z; data[3] = 0.00; } inline Vector* Vector::GetVector() { return this; } inline double Vector::GetX() { #ifdef DEBUG if (nrData < 1) { ::MessageBox(0, "Attempt to retrieve x-value of a vector\n" "With size smaller than 1 in function\n" " Vector::GetX();", "Error", MB_OK); exit(1); } #endif return data[0]; } inline double Vector::GetY() { #ifdef DEBUG if (nrData < 2) { ::MessageBox(0, "Attempt to retrieve the y value of a vector\n" "With size smaller than 2 in function\n" " Vector::GetY();", "Error", MB_OK); exit(1); } #endif return data[1]; } inline double Vector::GetZ() { #ifdef DEBUG if (nrData < 3) { ::MessageBox(0, "Attempt to retrieve the z value of a vector\n" "With size smaller than 2 in function\n" " Vector::GetZ();", "Error", MB_OK); exit(1); } #endif return data[2]; } inline void Vector::AddX(double x) { #ifdef DEBUG if (nrData < 1) { ::MessageBox(0, "Attempt to chance x-value to a vector\n" "With size smaller than 1 in function\n" " Vector::AddX(double);", "Error", MB_OK); exit(1); } #endif data[0] += x; } inline void Vector::AddY(double y) { #ifdef DEBUG if (nrData < 2) { ::MessageBox(0, "Attempt to chance y-value to a vector\n" "With size smaller than 2 in function\n" " Vector::AddY(double);", "Error", MB_OK); exit(1); } #endif data[1] += y; } inline void Vector::AddZ(double z) { #ifdef DEBUG if (nrData < 3) { ::MessageBox(0, "Attempt to chance z-value to a vector\n" "With size smaller than 3 in function\n" " Vector::AddZ(double);", "Error", MB_OK); exit(1); } #endif data[2] += z; } inline void Vector::SubtractX(double x) { #ifdef DEBUG if (nrData < 1) { ::MessageBox(0, "Attempt to chance x-value to a vector\n" "With size smaller than 1 in function\n" " Vector::SubtractX(double);", "Error", MB_OK); exit(1); } #endif data[0] -= x; } inline void Vector::SubtractY(double y) { #ifdef DEBUG if (nrData < 2) { ::MessageBox(0, "Attempt to chance y-value to a vector\n" "With size smaller than 2 in function\n" " Vector::SubractY(double);", "Error", MB_OK); exit(1); } #endif data[1] -= y; } inline void Vector::SubtractZ(double z) { #ifdef DEBUG if (nrData < 3) { ::MessageBox(0, "Attempt to chance z-value to a vector\n" "With size smaller than 3 in function\n" " Vector::SubtractZ(double);", "Error", MB_OK); exit(1); } #endif data[2] -= z; } inline Vector& Vector::operator= (Vector& other) { if (data) delete[] data; build(other.nrData); memcpy(data, other.data, nrData*sizeof(double)); return *this; } inline double& Vector::operator [](int index) { return *(data+index); } inline int Vector::getDim() { return nrData; } /*----------------------------------------------------------------------------- Some generic conversion routines ------------------------------------------------------------------------------*/ float CosD(float angle); float SinD(float angle); float Radians(float angle); int Round(float value); /* ---------------------------------------------------------------------------- And their inlined implementation ------------------------------------------------------------------------------*/ inline float CosD(float angle) { return cos(Radians(angle)); } inline float SinD(float angle) { return(Radians(angle)); } inline float Radians(float angle) { return (angle*PiOver180); } inline int Round(float value) { return ( (int) (value+0.5)); } /****************************************************************************** Matrix class ******************************************************************************/ class Matrix { protected: int rows; int columns; Vector* data; public: Matrix(); Matrix(int r, int c); Matrix(int r, int c, double* dta); Matrix(int r, int c, double** dta); Matrix(int r, int c, Vector*dta); Matrix(Matrix&); ~Matrix(); void build(int r, int c); Matrix& operator=(Matrix&); Vector& operator[](int); Vector operator ()(int); int getrows(); int getcols(); void norm(int scal); friend Vector operator*(Matrix mc, Vector vc); }; /*------------------------------------------------------------------------------ inline Matrix routines ------------------------------------------------------------------------------*/ inline Matrix::Matrix() { rows = 0; columns = 0; data = 0; } inline Matrix::Matrix(int r, int c) { build(r, c); } inline Matrix::~Matrix() { delete [] data; } inline Vector& Matrix::operator[] (int row) { return data[row]; } #endif // _MYMATH_H_