Original Post
I've written a function to test if two obb's collide but it doesn't work. Well sometimes it works fine but other times it doesn't. So can someone tell me what i'm doing wrong? You can download the demo and see for yourself here. (you can move around with wasd & q->down & e->up) My function takes 4 arguments: two objects(defined as an position and a rotation) and two boxes (defined as a position and a vector to the upperright corner). I've made a picture for clarity:
I use the seperating axes theorem to test if those two boxes collide. But I don't test on the cross product-axes yet because (according to wikipedia) they aren't that important and I want have it working first. My function is quite simple. First I calculate the matrix to rotate & translate from box1 to box2. Then I translate & rotate box2. Then I compare if the two boxes overlap on the x axis. If that's the case then the boxes aren't colliding. If they don't have any overlap go on with the function. Then I do the same thing on the Y and Z axes. And after that I translate & rotate box1. And test on the three axes again. The code: If you think the problem is in the matrix or vector classes you can download the source files here: vector.hpp matrix.hpp I hope everything is clear now. Sorry for my bad English (I'm Dutch). And thank you for reading (and hopefully replying on) my long post. /////////////////////////// Edit /////////////////////////// I made a little mistake in my dotproduct function that ruined my code. Even though all the code below (this post) isn't completly bug-free this was the biggest bug and making my code working was easy. Oliii, thank you for your help. This is the working code: matrix class: vector class: [Edited by - d1rk on November 7, 2009 10:58:16 AM]
I use the seperating axes theorem to test if those two boxes collide. But I don't test on the cross product-axes yet because (according to wikipedia) they aren't that important and I want have it working first. My function is quite simple. First I calculate the matrix to rotate & translate from box1 to box2. Then I translate & rotate box2. Then I compare if the two boxes overlap on the x axis. If that's the case then the boxes aren't colliding. If they don't have any overlap go on with the function. Then I do the same thing on the Y and Z axes. And after that I translate & rotate box1. And test on the three axes again. The code:
bool physics::boxboxtest(bbox box1, objectinst obj1, bbox box2, objectinst obj2p)
{
matrix44<double> transf1naar2 = (-box1.pos).gettransmatrix() * obj1.rot.getterugrotmatrix() * (-obj1.pos).gettransmatrix() * obj2.pos.gettransmatrix() * obj2.rot.getrotmatrix() * box2.pos.gettransmatrix();
/*
get...matrix calculates a matrix with the values of the vector.
so a.gettransmatrix() returns the translationmatrix that moves things in the direction of vector a.
a.getrotmatrix() returns a matrix that rotates points first a[0] degrees around the x axis and then a[1] degrees around the y axis and then a[2] degrees around the z axis.
"terug" is the dutch word for back so a.getterugrotmatrix() returns a matrix to rotate something back so that if vector b is (x,y,z)
b.transform(a.getrotmatrix() * a.getterugrotmatrix()) == b == (x,y,z)
I know i multiply the matrices in the wrong order. But i made my matrix class that way on purpose because it seems more logical to me.
A vector is rotated/translated in the same order as the matrices were multiplied.
*/
vector3d<double> transfpos2 = vector3d<double>(0,0,0).transform(transf1naar2),
transfmax2 = box2.max.transform(transf1naar2) - transfpos2;
for (short loop=0; loop<3; ++loop)
{
double
min1 = -(box1.max[loop]),
max1 = box1.max[loop],
min2 = transfpos2[loop] - fabs(transfmax2[loop]),
max2 = transfpos2[loop] + fabs(transfmax2[loop]);
if (max1 < min2 || max2 < min1)
{
return false;
}
}
matrix44<double> transf2naar1 = (-box2.pos).gettransmatrix() * obj2.rot.getterugrotmatrix() * (-obj2.pos).gettransmatrix() * obj1.pos.gettransmatrix() * obj1.rot.getrotmatrix() * box1.pos.gettransmatrix();
vector3d<double> transfpos1 = vector3d<double>(0,0,0).transform(transf2naar1),
transfmax1 = box1.max.transform(transf2naar1) - transfpos1;
for (short loop=0; loop<3; ++loop)
{
double
min2 = -(box2.max[loop]),
max2 = box2.max[loop],
min1 = transfpos1[loop] - fabs(transfmax1[loop]),
max1 = transfpos1[loop] + fabs(transfmax1[loop]);
if (max1 < min2 || max2 < min1)
{
return false;
}
}
return true;
}
inline void projeigenas (bbox box, unsigned char as, double& min, double& max)
{
min = box.pos[as] - box.max[as];
max = box.pos[as] + box.max[as];
}
inline void projas (bbox box, vector3d<double> as, double& min, double& max)
{
double
mid = scalairproduct(box.pos, as),
afstand = scalairproduct(box.max, as.abs());
min = mid - afstand;
max = mid + afstand;
}
inline bool testeigenas(bbox box1, matrix44<double> mat1, bbox box2, matrix44<double> terugmat2, vector3d<double> posverschil, unsigned char as)
{
vector3d<double> rotas = mat1.getrotkolom(as);
double min1, min2, max1, max2, verschil = scalairproduct(posverschil, rotas);
projeigenas(box1, as, min1, max1);
rotas = rotas.transform(terugmat2);
projas(box2, rotas, min2, max2);
if (max1 < min2+verschil || max2+verschil < min1)
{
return false;
}
return true;
}
inline bool testas(bbox box1, matrix44<double> terugmat1, bbox box2, matrix44<double> terugmat2, vector3d<double> posverschil, vector3d<double> as)
{
double min1, min2, max1, max2, verschil = scalairproduct(posverschil, as);
vector3d<double> rotas = as.transform(terugmat1);
projas(box1, rotas, min1, max1);
rotas = as.transform(terugmat2);
projas(box2, rotas, min2, max2);
if (max1 < min2+verschil || max2+verschil < min1)
{
return false;
}
return true;
}
bool physics::boxboxtest(bbox box1, objectinst* obj1p, bbox box2, objectinst* obj2p)
{
objectinst obj1 = *obj1p, obj2 = *obj2p;
obj1.pos += obj1.beweging;
obj2.pos += obj2.beweging;
obj1.rot += obj1.draaing;
obj2.rot += obj2.draaing;
matrix44<double> mat1 = obj1.rot.getrotmatrix();
matrix44<double> mat2 = obj2.rot.getrotmatrix();
matrix44<double> terugmat1 = obj1.rot.getterugrotmatrix();
matrix44<double> terugmat2 = obj2.rot.getterugrotmatrix();
for (unsigned char loop=0; loop<3; ++loop)
{
if(!testeigenas(box1, mat1, box2, terugmat2, obj2.pos - obj1.pos, loop))
{
return false;
}
if(!testeigenas(box2, mat2, box1, terugmat1, obj1.pos - obj2.pos, loop))
{
return false;
}
for (short loop2=0; loop2<3; ++loop2)
{
if(!testas(box1, terugmat1, box2, terugmat2, obj2.pos - obj1.pos,
kruisproduct(mat1.getrotkolom(loop), mat2.getrotkolom(loop2)) ))
{
return false;
}
}
}
return true;
}
#ifndef matrix_bib
#define matrix_bib
#include <string>
#include "basisbib.hpp"
template <class getal> class vector3d;
template <class getal>
class matrix44
{
getal coords[4][4];
public:
void maakeenheidsm ()
{
coords[0][0] = 1; coords[0][1] = 0; coords[0][2] = 0; coords[0][3] = 0;
coords[1][0] = 0; coords[1][1] = 1; coords[1][2] = 0; coords[1][3] = 0;
coords[2][0] = 0; coords[2][1] = 0; coords[2][2] = 1; coords[2][3] = 0;
coords[3][0] = 0; coords[3][1] = 0; coords[3][2] = 0; coords[3][3] = 1;
}
matrix44()
{
maakeenheidsm();
}
void set (getal coordsbuff[][4])
{
for (int kolom=0; kolom<4; ++kolom)
{
for (int rij=0; rij<4; ++rij)
{
coords[rij][kolom] = coordsbuff[rij][kolom];
}
}
}
matrix44(getal coordsbuff[][4])
{
set(coordsbuff);
}
void set (getal xx, getal yx, getal zx, getal wx, getal xy, getal yy, getal zy, getal wy, getal xz, getal yz, getal zz, getal wz, getal xw, getal yw, getal zw, getal ww)
{
coords[0][0] = xx; coords[0][1] = yx; coords[0][2] = zx; coords[0][3] = wx;
coords[1][0] = xy; coords[1][1] = yy; coords[1][2] = zy; coords[1][3] = wy;
coords[2][0] = xz; coords[2][1] = yz; coords[2][2] = zz; coords[2][3] = wz;
coords[3][0] = xw; coords[3][1] = yw; coords[3][2] = zw; coords[3][3] = ww;
}
matrix44 (getal xx, getal yx, getal zx, getal wx, getal xy, getal yy, getal zy, getal wy, getal xz, getal yz, getal zz, getal wz, getal xw, getal yw, getal zw, getal ww)
{
coords[0][0] = xx; coords[0][1] = yx; coords[0][2] = zx; coords[0][3] = wx;
coords[1][0] = xy; coords[1][1] = yy; coords[1][2] = zy; coords[1][3] = wy;
coords[2][0] = xz; coords[2][1] = yz; coords[2][2] = zz; coords[2][3] = wz;
coords[3][0] = xw; coords[3][1] = yw; coords[3][2] = zw; coords[3][3] = ww;
}
matrix44 operator = (matrix44 temp)
{
for (int kolom=0; kolom<4; ++kolom)
{
for (int rij=0; rij<4; ++rij)
{
coords[rij][kolom] = temp(rij, kolom);
}
}
return *this;
}
getal& operator () (unsigned int x, unsigned int y)
{
return coords[x][y];
}
matrix44 operator * (matrix44 temp)
{
matrix44 temp2;
for (int kolom=0; kolom<4; ++kolom)
{
for (int rij=0; rij<4; ++rij)
{
temp2(rij,kolom) = coords[rij][0] * temp(0,kolom) + coords[rij][1] * temp(1,kolom) + coords[rij][2] * temp(2,kolom) + coords[rij][3] * temp(3,kolom);
}
}
return temp2;
}
string output()
{
return ("<table><tr><td rowspan =\"4\" style =\"font-size: 95px; padding:0px; font-family:Calibri;\">[</td><td>"
+ stringvan<getal>(coords[0][0]) + "</td><td>" + stringvan<getal>(coords[0][1]) + "</td><td>" + stringvan<getal>(coords[0][2]) + "</td><td>" + stringvan<getal>(coords[0][3]) + "</td><td rowspan =\"4\" style =\" font-size: 95px; padding:0px; font-family:Calibri;\">]</td></tr>" +
"<tr><td>" + stringvan<getal>(coords[1][0]) + "</td><td>" + stringvan<getal>(coords[1][1]) + "</td><td>" + stringvan<getal>(coords[1][2]) + "</td><td>" + stringvan<getal>(coords[1][3]) + "</td></tr>" +
"<tr><td>" + stringvan<getal>(coords[2][0]) + "</td><td>" + stringvan<getal>(coords[2][1]) + "</td><td>" + stringvan<getal>(coords[2][2]) + "</td><td>" + stringvan<getal>(coords[2][3]) + "</td></tr>" +
"<tr><td>" + stringvan<getal>(coords[3][0]) + "</td><td>" + stringvan<getal>(coords[3][1]) + "</td><td>" + stringvan<getal>(coords[3][2]) + "</td><td>" + stringvan<getal>(coords[3][3]) + "</td></tr><table>");
}
vector3d<getal> getrotrij (unsigned char x)
{
return vector3d<getal>(coords[x][0], coords[x][1], coords[x][2]);
}
vector3d<getal> getrotkolom (unsigned char x)
{
return vector3d<getal>(coords[0][x], coords[1][x], coords[2][x]);
}
vector3d<getal> getverplaatsing ()
{
return vector3d<getal>(coords[0][3], coords[1][3], coords[2][3]);
}
};
#endif
#ifndef vector_bib
#define vector_bib
#include <string>
#include "basisbib.hpp"
#include "matrix.hpp"
using namespace std;
template <class getal>
class vector2d
{
getal coords[2];
public:
inline vector2d()
{
coords[0] = 0;
coords[1] = 0;
}
inline vector2d(getal x, getal y)
{
coords[0] = x;
coords[1] = y;
}
inline vector2d(getal coordsbuff[2])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
}
inline getal* get()
{
return coords;
}
inline getal& operator [] (unsigned int temp)
{
return coords[temp];
}
inline getal x()
{
return coords[0];
}
inline getal y()
{
return coords[1];
}
inline vector2d operator + (vector2d temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] + temp.coords[0];
temp2.coords[1] = coords[1] + temp.coords[1];
return temp2;
}
inline vector2d operator - (vector2d temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] - temp.coords[0];
temp2.coords[1] = coords[1] - temp.coords[1];
return temp2;
}
inline vector2d operator * (vector2d temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] * temp.coords[0];
temp2.coords[1] = coords[1] * temp.coords[1];
return temp2;
}
inline vector2d operator / (vector2d temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] / temp.coords[0];
temp2.coords[1] = coords[1] / temp.coords[1];
return temp2;
}
inline vector2d operator = (vector2d temp)
{
coords[0] = temp.coords[0];
coords[1] = temp.coords[1];
return *this;
}
inline vector2d operator += (vector2d temp)
{
coords[0] += temp.coords[0];
coords[1] += temp.coords[1];
return *this;
}
inline vector2d operator -= (vector2d temp)
{
coords[0] -= temp.coords[0];
coords[1] -= temp.coords[1];
return *this;
}
inline vector2d operator *= (vector2d temp)
{
coords[0] *= temp.coords[0];
coords[1] *= temp.coords[1];
return *this;
}
inline vector2d operator /= (vector2d temp)
{
coords[0] /= temp.coords[0];
coords[1] /= temp.coords[1];
return *this;
}
inline vector2d operator * (getal temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] * temp;
temp2.coords[1] = coords[1] * temp;
return temp2;
}
inline vector2d operator / (getal temp)
{
vector2d temp2;
temp2.coords[0] = coords[0] / temp;
temp2.coords[1] = coords[1] / temp;
return temp2;
}
inline vector2d operator *= (getal temp)
{
coords[0] *= temp;
coords[1] *= temp;
return *this;
}
inline vector2d operator /= (getal temp)
{
coords[0] /= temp;
coords[1] /= temp;
return *this;
}
inline bool operator == (vector2d temp)
{
return (coords[0] == temp.coords[0] && coords[1] == temp.coords[1]);
}
inline bool operator != (vector2d temp)
{
return !(coords[0] == temp.coords[0] && coords[1] == temp.coords[1]);
}
inline bool operator < (vector2d temp)
{
return (coords[0] < temp.coords[0] && coords[1] < temp.coords[1]);
}
inline bool operator > (vector2d temp)
{
return (coords[0] > temp.coords[0] && coords[1] > temp.coords[1]);
}
inline bool operator <= (vector2d temp)
{
return (coords[0] <= temp.coords[0] && coords[1] <= temp.coords[1]);
}
inline bool operator >= (vector2d temp)
{
return (coords[0] >= temp.coords[0] && coords[1] >= temp.coords[1]);
}
inline void set(getal x, getal y)
{
coords[0] = x;
coords[1] = y;
}
inline void set(getal coordsbuff[2])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
}
inline void set(vector2d temp)
{
*this = temp;
}
inline void operator () (getal x, getal y)
{
coords[0] = x;
coords[1] = y;
}
inline void operator () (getal coordsbuff[2])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
}
inline void operator () (vector2d temp)
{
*this = temp;
}
};
template <class getal>
class vector3d
{
getal coords[3];
public:
inline vector3d()
{
coords[0] = 0;
coords[1] = 0;
coords[2] = 0;
}
inline vector3d(getal x, getal y, getal z)
{
coords[0] = x;
coords[1] = y;
coords[2] = z;
}
inline vector3d(getal coordsbuff[3])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
coords[2] = coordsbuff[2];
}
inline getal* get()
{
return coords;
}
inline getal& operator [] (unsigned int temp)
{
return coords[temp];
}
inline getal x()
{
return coords[0];
}
inline getal y()
{
return coords[1];
}
inline getal z()
{
return coords[2];
}
inline vector3d operator + (vector3d temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] + temp.coords[0];
temp2.coords[1] = coords[1] + temp.coords[1];
temp2.coords[2] = coords[2] + temp.coords[2];
return temp2;
}
inline vector3d operator - (vector3d temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] - temp.coords[0];
temp2.coords[1] = coords[1] - temp.coords[1];
temp2.coords[2] = coords[2] - temp.coords[2];
return temp2;
}
inline vector3d operator * (vector3d temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] * temp.coords[0];
temp2.coords[1] = coords[1] * temp.coords[1];
temp2.coords[2] = coords[2] * temp.coords[2];
return temp2;
}
inline vector3d operator / (vector3d temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] / temp.coords[0];
temp2.coords[1] = coords[1] / temp.coords[1];
temp2.coords[2] = coords[2] / temp.coords[2];
return temp2;
}
inline vector3d operator = (vector3d temp)
{
coords[0] = temp.coords[0];
coords[1] = temp.coords[1];
coords[2] = temp.coords[2];
return *this;
}
inline vector3d operator += (vector3d temp)
{
coords[0] += temp.coords[0];
coords[1] += temp.coords[1];
coords[2] += temp.coords[2];
return *this;
}
inline vector3d operator -= (vector3d temp)
{
coords[0] -= temp.coords[0];
coords[1] -= temp.coords[1];
coords[2] -= temp.coords[2];
return *this;
}
inline vector3d operator *= (vector3d temp)
{
coords[0] *= temp.coords[0];
coords[1] *= temp.coords[1];
coords[2] *= temp.coords[2];
return *this;
}
inline vector3d operator /= (vector3d temp)
{
coords[0] /= temp.coords[0];
coords[1] /= temp.coords[1];
coords[2] /= temp.coords[2];
return *this;
}
inline vector3d operator * (getal temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] * temp;
temp2.coords[1] = coords[1] * temp;
temp2.coords[2] = coords[2] * temp;
return temp2;
}
inline vector3d operator / (getal temp)
{
vector3d temp2;
temp2.coords[0] = coords[0] / temp;
temp2.coords[1] = coords[1] / temp;
temp2.coords[2] = coords[2] / temp;
return temp2;
}
inline vector3d operator *= (getal temp)
{
coords[0] *= temp;
coords[1] *= temp;
coords[2] *= temp;
return *this;
}
inline vector3d operator /= (getal temp)
{
coords[0] /= temp;
coords[1] /= temp;
coords[2] /= temp;
return *this;
}
inline bool operator == (vector3d temp)
{
return (coords[0] == temp.coords[0] && coords[1] == temp.coords[1] && coords[2] == temp.coords[2]);
}
inline bool operator != (vector3d temp)
{
return !(coords[0] == temp.coords[0] && coords[1] == temp.coords[1] && coords[2] == temp.coords[2]);
}
inline bool operator < (vector3d temp)
{
return (coords[0] < temp.coords[0] && coords[1] < temp.coords[1] && coords[2] < temp.coords[2]);
}
inline bool operator > (vector3d temp)
{
return (coords[0] > temp.coords[0] && coords[1] > temp.coords[1] && coords[2] > temp.coords[2]);
}
inline bool operator <= (vector3d temp)
{
return (coords[0] <= temp.coords[0] && coords[1] <= temp.coords[1] && coords[2] <= temp.coords[2]);
}
inline bool operator >= (vector3d temp)
{
return (coords[0] >= temp.coords[0] && coords[1] >= temp.coords[1] && coords[2] >= temp.coords[2]);
}
inline void set (getal x, getal y, getal z)
{
coords[0] = x;
coords[1] = y;
coords[2] = z;
}
inline void set (getal coordsbuff[3])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
coords[2] = coordsbuff[2];
}
inline void set (vector3d temp)
{
*this = temp;
}
inline void operator () (getal x, getal y, getal z)
{
coords[0] = x;
coords[1] = y;
coords[2] = z;
}
inline void operator () (getal coordsbuff[3])
{
coords[0] = coordsbuff[0];
coords[1] = coordsbuff[1];
coords[2] = coordsbuff[2];
}
inline void operator () (vector3d temp)
{
*this = temp;
}
inline vector3d operator - ()
{
return vector3d(-coords[0], -coords[1], -coords[2]);
}
inline vector3d abs()
{
return vector3d((coords[0]>0) ? coords[0] : -coords[0], (coords[1]>0) ? coords[1] : -coords[1], (coords[2]>0) ? coords[2] : -coords[2]);
}
inline vector3d unitvector ()
{
getal lengte = sqrt(double(coords[0]*coords[0]+coords[1]*coords[1]+coords[2]*coords[2]));
return *this/lengte;
}
inline getal lengte()
{
return getal(sqrt(double(coords[0]*coords[0] + coords[1]*coords[1] + coords[2]*coords[2])));
}
inline string output ()
{
return "(" + stringvan<getal>(coords[0]) + " | " + stringvan<getal>(coords[1]) + " | " + stringvan<getal>(coords[2]) + ")";
}
inline getal laagste ()
{
return (((coords[0]<coords[1]) ? coords[0] : coords[1])<coords[2]) ? ((coords[0]<coords[1]) ? coords[0] : coords[1]) : coords[2];
}
inline getal hoogste ()
{
return (((coords[0]>coords[1]) ? coords[0] : coords[1])>coords[2]) ? ((coords[0]>coords[1]) ? coords[0] : coords[1]) : coords[2];
}
inline vector3d getas (unsigned int temp)
{
vector3d<getal> temp2(0,0,0);
temp2[temp] = coords[temp];
return temp2;
}
inline vector3d roteer(vector3d rot)
{
vector3d temp2(coords);
if (rot[0] != 0)
{
temp2(temp2.x(), temp2[1]*gcos(rot[0]) - temp2[2]*gsin(rot[0]), temp2[1]*gsin(rot[0]) + temp2[2]*gcos(rot[0]));
}
if (rot[1] != 0)
{
temp2(temp2[2]*gsin(rot[1]) + temp2[0]*gcos(rot[1]), temp2.y(), temp2[2]*gcos(rot[1]) - temp2[0]*gsin(rot[1]));
}
if (rot[2] != 0)
{
temp2(temp2[0]*gcos(rot[2]) - temp2[1]*gsin(rot[2]), temp2[0]*gsin(rot[2]) + temp2[1]*gcos(rot[2]), temp2.z());
}
return temp2;
}
inline vector3d roteer(matrix44<getal> buffmat)
{
vector3d buffvec;
buffvec[0] = coords[0] * buffmat(0,0) + coords[1] * buffmat(0,1) + coords[2] * buffmat(0,2);
buffvec[1] = coords[0] * buffmat(1,0) + coords[1] * buffmat(1,1) + coords[2] * buffmat(1,2);
buffvec[2] = coords[0] * buffmat(2,0) + coords[1] * buffmat(2,1) + coords[2] * buffmat(2,2);
return (buffvec);
}
inline vector3d transform(matrix44<getal> buffmat)
{
vector3d buffvec;
buffvec[0] = coords[0] * buffmat(0,0) + coords[1] * buffmat(0,1) + coords[2] * buffmat(0,2) + buffmat(0,3);
buffvec[1] = coords[0] * buffmat(1,0) + coords[1] * buffmat(1,1) + coords[2] * buffmat(1,2) + buffmat(1,3);
buffvec[2] = coords[0] * buffmat(2,0) + coords[1] * buffmat(2,1) + coords[2] * buffmat(2,2) + buffmat(2,3);
return (buffvec);
}
inline matrix44<getal> getrotmatrix()
{
return matrix44<getal>
(
1, 0, 0, 0,
0, gcos(coords[0]), -gsin(coords[0]), 0,
0, gsin(coords[0]), gcos(coords[0]), 0,
0, 0, 0, 1
) * matrix44<getal>
(
gcos(coords[1]), 0, gsin(coords[1]), 0,
0, 1, 0, 0,
-gsin(coords[1]), 0, gcos(coords[1]), 0,
0, 0, 0, 1
) * matrix44<getal>
(
gcos(coords[2]), -gsin(coords[2]), 0, 0,
gsin(coords[2]), gcos(coords[2]), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
}
inline matrix44<getal> getterugrotmatrix()
{
return matrix44<getal>
(
gcos(-coords[2]), -gsin(-coords[2]), 0, 0,
gsin(-coords[2]), gcos(-coords[2]), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
) * matrix44<getal>
(
gcos(-coords[1]), 0, gsin(-coords[1]), 0,
0, 1, 0, 0,
-gsin(-coords[1]), 0, gcos(-coords[1]), 0,
0, 0, 0, 1
) * matrix44<getal>
(
1, 0, 0, 0,
0, gcos(-coords[0]), -gsin(-coords[0]), 0,
0, gsin(-coords[0]), gcos(-coords[0]), 0,
0, 0, 0, 1
);
}
inline matrix44<getal> gettransmatrix()
{
return matrix44<getal>
(
1, 0, 0, coords[0],
0, 1, 0, coords[1],
0, 0, 1, coords[2],
0, 0, 0, 1
);
}
inline matrix44<getal> getschlmatrix()
{
return matrix44<getal>
(
coords[0], 0, 0, 0,
0, coords[1], 0, 0,
0, 0, coords[2], 0,
0, 0, 0, 1
);
}
};
template <class getal>
getal scalairproduct(vector2d<getal> v1, vector2d<getal> v2)
{
return v1[0] * v2[0] + v1[1] * v2[1];
}
template <class getal>
getal scalairproduct(vector3d<getal> v1, vector3d<getal> v2)
{
return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
template <class getal>
vector3d<getal> kruisproduct(vector3d<getal> v1, vector3d<getal> v2)
{
return vector3d<getal> (v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]);
}
#endif