This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/math/Matrix3.h
2018-10-25 11:50:12 +02:00

250 lines
7.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © Copyright 2014 Urheberrechtshinweis
* Alle Rechte vorbehalten / All Rights Reserved
*
* Programmcode ist urheberrechtlich geschuetzt.
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
* Keine Verwendung ohne explizite Genehmigung.
* (vgl. § 106 ff UrhG / § 97 UrhG)
*/
#ifndef INDOOR_MATH_MATRIX3_H
#define INDOOR_MATH_MATRIX3_H
#include <initializer_list>
#include <cmath>
#include "../Assertions.h"
class Matrix3 {
private:
float data[9];
public:
Matrix3(std::initializer_list<float> lst) {
int idx = 0;
for (float f : lst) {
data[idx] = f; ++idx;
}
}
static Matrix3 identity() {
return Matrix3( {1,0,0, 0,1,0, 0,0,1} );
}
static Matrix3 getRotationDeg(const float degX, const float degY, const float degZ) {
return getRotationRad(degX/180.0f*M_PI, degY/180.0f*M_PI, degZ/180.0f*M_PI);
}
static Matrix3 getRotationRad(const float radX, const float radY, const float radZ) {
const float g = radX; const float b = radY; const float a = radZ;
const float a11 = std::cos(a)*std::cos(b);
const float a12 = std::cos(a)*std::sin(b)*std::sin(g)-std::sin(a)*std::cos(g);
const float a13 = std::cos(a)*std::sin(b)*std::cos(g)+std::sin(a)*std::sin(g);
const float a21 = std::sin(a)*std::cos(b);
const float a22 = std::sin(a)*std::sin(b)*std::sin(g)+std::cos(a)*std::cos(g);
const float a23 = std::sin(a)*std::sin(b)*std::cos(g)-std::cos(a)*std::sin(g);
const float a31 = -std::sin(b);
const float a32 = std::cos(b)*std::sin(g);
const float a33 = std::cos(b)*std::cos(g);
return Matrix3({
a11, a12, a13,
a21, a22, a23,
a31, a32, a33,
});
}
static Matrix3 getRotationVec(const float nx, const float ny, const float nz, const float mag) {
Assert::isNotNaN(nx, "detected NaN");
Assert::isNotNaN(ny, "detected NaN");
Assert::isNotNaN(nz, "detected NaN");
Assert::isNotNaN(mag, "detected NaN");
const float c = std::cos(mag);
const float s = std::sin(mag);
return Matrix3({
c+nx*nx*(1-c), nx*ny*(1-c)+nz*s, nx*nz*(1-c)-ny*s,
ny*nx*(1-c)-nz*s, c+ny*ny*(1-c), ny*nz*(1-c)+nx*s,
nz*nx*(1-c)+ny*s, nz*ny*(1-c)-nx*s, c+nz*nz*(1-c)
});
}
static Matrix3 getRotationRadX(const float x) {
return Matrix3({
1, 0, 0,
0, cos(x), -sin(x),
0, sin(x), cos(x)
});
}
static Matrix3 getRotationRadY(const float y) {
return Matrix3({
cos(y), 0, sin(y),
0, 1, 0,
-sin(y),0, cos(y)
});
}
static Matrix3 getRotationRadZ(const float z) {
return Matrix3({
cos(z), -sin(z), 0,
sin(z), cos(z), 0,
0, 0, 1
});
}
Matrix3 transposed() const {
return Matrix3({
data[0], data[3], data[6],
data[1], data[4], data[7],
data[2], data[5], data[8]
});
}
static Matrix3 getTranslation(const float x, const float y) {
return Matrix3({
1, 0, x,
0, 1, y,
0, 0, 1,
});
}
static Matrix3 getScale(const float x, const float y) {
return Matrix3({
x, 0, 0,
0, y, 0,
0, 0, 1,
});
}
float operator [] (const int idx) const {return data[idx];}
bool operator == (const Matrix3& o) const {
for (int i = 0; i < 9; ++i) {
if (data[i] != o.data[i]) {return false;}
}
return true;
}
Matrix3 operator * (const float v) const {
return Matrix3({
data[0]*v, data[1]*v, data[2]*v,
data[3]*v, data[4]*v, data[5]*v,
data[6]*v, data[7]*v, data[8]*v,
});
}
Matrix3 operator + (const Matrix3& m) const {
return Matrix3({
data[0]+m.data[0], data[1]+m.data[1], data[2]+m.data[2],
data[3]+m.data[3], data[4]+m.data[4], data[5]+m.data[5],
data[6]+m.data[6], data[7]+m.data[7], data[8]+m.data[8],
});
}
Matrix3 operator * (const Matrix3& m) const {
return Matrix3({
data[0]*m.data[0] + data[1]*m.data[3] + data[2]*m.data[6], data[0]*m.data[1] + data[1]*m.data[4] + data[2]*m.data[7], data[0]*m.data[2] + data[1]*m.data[5] + data[2]*m.data[8],
data[3]*m.data[0] + data[4]*m.data[3] + data[5]*m.data[6], data[3]*m.data[1] + data[4]*m.data[4] + data[5]*m.data[7], data[3]*m.data[2] + data[4]*m.data[5] + data[5]*m.data[8],
data[6]*m.data[0] + data[7]*m.data[3] + data[8]*m.data[6], data[6]*m.data[1] + data[7]*m.data[4] + data[8]*m.data[7], data[6]*m.data[2] + data[7]*m.data[5] + data[8]*m.data[8],
});
}
};
struct Vector3 {
float x,y,z;
Vector3() : x(0), y(0), z(0) {;}
Vector3(float x, float y, float z) : x(x), y(y), z(z) {;}
Vector3 operator + (const Vector3 o) const {
return Vector3(x+o.x, y+o.y, z+o.z);
}
Vector3 operator - (const Vector3 o) const {
return Vector3(x-o.x, y-o.y, z-o.z);
}
Vector3 operator * (const Vector3 o) const {
return Vector3(x*o.x, y*o.y, z*o.z);
}
Vector3 operator * (const float v) const {
return Vector3(x*v, y*v, z*v);
}
Vector3 operator / (const float v) const {
return Vector3(x/v, y/v, z/v);
}
Vector3& operator += (const Vector3 o) {
this->x += o.x;
this->y += o.y;
this->z += o.z;
return *this;
}
Vector3& operator -= (const Vector3 o) {
this->x -= o.x;
this->y -= o.y;
this->z -= o.z;
return *this;
}
// Vector& operator = (const float val) {
// this->x = val;
// this->y = val;
// this->z = val;
// return *this;
// }
bool operator == (const Vector3 o) const {
return (x==o.x) && (y==o.y) && (z==o.z);
}
float norm() const {
return std::sqrt(x*x + y*y + z*z);
}
Vector3 normalized() const {
const float n = norm();
return Vector3(x/n, y/n, z/n);
}
Vector3 cross(const Vector3 o) const {
return Vector3(
y*o.z - z*o.y,
z*o.x - x*o.z,
x*o.y - y*o.x
);
}
float dot(const Vector3 o) const {
return (x*o.x) + (y*o.y) + (z*o.z);
}
};
inline Vector3 operator * (const Matrix3& mat, const Vector3& vec) {
return Vector3(
(mat[ 0]*vec.x + mat[ 1]*vec.y + mat[ 2]*vec.z),
(mat[ 3]*vec.x + mat[ 4]*vec.y + mat[ 5]*vec.z),
(mat[ 6]*vec.x + mat[ 7]*vec.y + mat[ 8]*vec.z)
);
}
//inline Matrix4 operator * (const Matrix4& m1, const Matrix4& m2) {
// return Matrix4({
// m1[ 0]*m2[ 0] + m1[ 1]*m2[ 4] + m1[ 2]*m2[ 8] + m1[ 3]*m2[12], m1[ 0]*m2[ 1] + m1[ 1]*m2[ 5] + m1[ 2]*m2[ 9] + m1[ 3]*m2[13], m1[ 0]*m2[ 2] + m1[ 1]*m2[ 6] + m1[ 2]*m2[10] + m1[ 3]*m2[14], m1[ 0]*m2[ 3] + m1[ 1]*m2[ 7] + m1[ 2]*m2[11] + m1[ 3]*m2[15],
// m1[ 4]*m2[ 0] + m1[ 5]*m2[ 4] + m1[ 6]*m2[ 8] + m1[ 7]*m2[12], m1[ 4]*m2[ 1] + m1[ 5]*m2[ 5] + m1[ 6]*m2[ 9] + m1[ 7]*m2[13], m1[ 4]*m2[ 2] + m1[ 5]*m2[ 6] + m1[ 6]*m2[10] + m1[ 7]*m2[14], m1[ 4]*m2[ 3] + m1[ 5]*m2[ 7] + m1[ 6]*m2[11] + m1[ 7]*m2[15],
// m1[ 8]*m2[ 0] + m1[ 9]*m2[ 4] + m1[10]*m2[ 8] + m1[11]*m2[12], m1[ 8]*m2[ 1] + m1[ 9]*m2[ 5] + m1[10]*m2[ 9] + m1[11]*m2[13], m1[ 8]*m2[ 2] + m1[ 9]*m2[ 6] + m1[10]*m2[10] + m1[11]*m2[14], m1[ 8]*m2[ 3] + m1[ 9]*m2[ 7] + m1[10]*m2[11] + m1[11]*m2[15],
// m1[12]*m2[ 0] + m1[13]*m2[ 4] + m1[14]*m2[ 8] + m1[15]*m2[12], m1[12]*m2[ 1] + m1[13]*m2[ 5] + m1[14]*m2[ 9] + m1[15]*m2[13], m1[12]*m2[ 2] + m1[13]*m2[ 6] + m1[14]*m2[10] + m1[15]*m2[14], m1[12]*m2[ 3] + m1[13]*m2[ 7] + m1[14]*m2[11] + m1[15]*m2[15]
// });
//}
#endif // INDOOR_MATH_MATRIX3_H