457 lines
11 KiB
C++
Executable file
457 lines
11 KiB
C++
Executable file
/* -*- 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 <Include/compiler.h>
|
|
|
|
#include <math.h>
|
|
#include STL_FSTREAM
|
|
#include STL_IOMANIP
|
|
|
|
FG_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_
|
|
|
|
|