This is old C++ code originally intended to be a playground for 3D math.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

220 lines
6.5 KiB

/**
* \file V_K4.h
*
* \brief Klasse die einen 4er-Vektor mathematisch beschreibt und handled.
*
* Hier gibt alles was man für Vektoren so braucht (Vektorprodukt,
* Skalarprodukt, Addition, Subtraktion, Multiplikation mit Matrize)
*
* \author Georg Steffers <georg@steffers.org> [gs]
*
* \date 04.12.2003
*
* \version ..2002 [gs]: erste funktionierende Implementation
* \version 18.12.2003 [gs]: Vergleichsoperator hinzugef&uuml;gt.
*/
/*
* Copyright (C)2003 Georg Steffers
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __V_K4_H__
#define __V_K4_H__
#include <cmath>
#include <iostream>
#include "Mmn.h"
/**
* \brief Winkel auf -360 bis +360 beschr&auml;nken und als double
* handhaben.
*
* Wird ein Winkel < -360 oder > +360 angegeben, so wird sein Vorkommateil
* auf diesen Bereich gestuzt und der Nachkommateil hinzuaddiert.
*/
#define WINKEL(x) ((double)((int)(x)%360)+(double)(x)-(int)(x))
#define BOGENMASS(x) (WINKEL((x))*M_PI/180)
#define RAD(x) (BOGENMASS((x)))
#define GRAD(x) (WINKEL((x))*180/M_PI)
#define SQR(x) ((x)*(x))
using namespace std;
template <class K>
class V_K4 : public Mmn<K> {
public:
V_K4() : Mmn<K>(4, 1) {}
V_K4(Mmn<K> m) : Mmn<K>(m) {}
V_K4(K* a) : Mmn<K>(a, 4, 1) {}
V_K4(K e1, K e2, K e3, K e4=0) : Mmn<K>(4,1) {
_a[0][0]=e1; _a[1][0]=e2;
_a[2][0]=e3; _a[3][0]=e4;
}
const K& operator[](unsigned i) const { return _a[i>m-1?m-1:i][0]; }
K& operator[](unsigned i) { return _a[i>m-1?m-1:i][0]; }
K& X(unsigned i) { return (*this)[0]; }
K& Y(unsigned i) { return (*this)[1]; }
K& Z(unsigned i) { return (*this)[2]; }
K& W(unsigned i) { return (*this)[3]; }
K v_betr(void) const { return sqrt(*this % *this); }
V_K4<K> v_norm(void) const { return *this * (1/v_betr()); }
K operator% (const V_K4<K>&) const;
V_K4<K> operator| (const V_K4<K>&) const;
bool operator== (const V_K4<K>& v) const {
if(this->m==v.m &&
this->n==v.n) {
for(unsigned i=0; i<m; i++)
for(unsigned j=0; j<n; j++)
if(_a[i][j]!=v._a[i][j])
return false;
}
else
return false;
return true;
}
};
template <class K>
inline ostream& operator<<(ostream& strm, const V_K4<K>& A) {
A.print(strm);
return strm;
}
#include "V_K4_tpl.h"
/**
* \brief Liefert die Matrize zur Rotation eines Punktes um einen
* beliebigen Vektor
*/
class mat_rot_axe : public Mmn<double> {
public:
mat_rot_axe(double* a) : Mmn<double>(a, 4, 4) {}
mat_rot_axe(double w=0,
V_K4<double> const& axe=V_K4<double>(0,0,1,0)) {
V_K4<double> u(axe.v_norm());
double A[4][4]={{SQR(u[0])+cos(RAD(w))*(1-SQR(u[0])),
u[0]*u[1]*(1-cos(RAD(w)))-u[2]*sin(RAD(w)),
u[2]*u[0]*(1-cos(RAD(w)))+u[1]*sin(RAD(w)),
0},
{u[0]*u[1]*(1-cos(RAD(w)))+u[2]*sin(RAD(w)),
SQR(u[1])+cos(RAD(w))*(1-SQR(u[1])),
u[1]*u[2]*(1-cos(RAD(w)))-u[0]*sin(RAD(w)),
0},
{u[2]*u[0]*(1-cos(RAD(w)))-u[1]*sin(RAD(w)),
u[1]*u[2]*(1-cos(RAD(w)))+u[0]*sin(RAD(w)),
SQR(u[2])+cos(RAD(w))*(1-SQR(u[2])),
0},
{0,0,0,1}};
*this=mat_rot_axe((double*)A);
}
};
/**
* \brief Liefert die Matrize zur Rotation eines Punktes um die
* X-Achse
*/
class mat_rot_x : public Mmn<double> {
public:
mat_rot_x(double* a) : Mmn<double>(a, 4, 4) {}
mat_rot_x(double w=0) {
double A[4][4]={{1,0,0,0},
{0,cos(RAD(w)),-sin(RAD(w)),0},
{0,sin(RAD(w)),cos(RAD(w)),0},
{0,0,0,1}};
*this=mat_rot_x((double*)A);
}
};
/**
* \brief Liefert die Matrize zur Rotation eines Punktes um die
* Y-Achse
*/
class mat_rot_y : public Mmn<double> {
public:
mat_rot_y(double* a) : Mmn<double>(a, 4, 4) {}
mat_rot_y(double w=0) {
double A[4][4]={{cos(RAD(w)),0,sin(RAD(w)),0},
{0,1,0,0},
{-sin(RAD(w)),0,cos(RAD(w)),0},
{0,0,0,1}};
*this=mat_rot_y((double*)A);
}
};
/**
* \brief Liefert die Matrize zur Rotation eines Punktes um die
* Z-Achse
*/
class mat_rot_z : public Mmn<double> {
public:
mat_rot_z(double* a) : Mmn<double>(a, 4, 4) {}
mat_rot_z(double w=0) {
double A[4][4]={{cos(RAD(w)),-sin(RAD(w)),0,0},
{sin(RAD(w)),cos(RAD(w)),0,0},
{0,0,1,0},
{0,0,0,1}};
*this=mat_rot_z((double*)A);
}
};
/**
* \brief Liefert die Matrize zur Verschiebung eines Punktes um
* tx. ty und tz
*/
class mat_translate : public Mmn<double> {
public:
mat_translate(double* a) : Mmn<double>(a, 4, 4) {}
mat_translate(double tx=0, double ty=0, double tz=0) {
double A[4][4]={{1,0,0,tx},
{0,1,0,ty},
{0,0,1,tz},
{0,0,0,1}};
*this=mat_translate((double*)A);
}
};
/**
* \brief Liefert die Matrize zur Verformung eines Punktes um
* sx. sy und sz
*/
class mat_transform : public Mmn<double> {
public:
mat_transform(double* a) : Mmn<double>(a, 4, 4) {}
mat_transform(double sx=0, double sy=0, double sz=0) {
double A[4][4]={{sx,0,0,0},
{0,sy,0,0},
{0,0,sz,0},
{0,0,0,1}};
*this=mat_transform((double*)A);
}
};
#endif // __V_K4_H__