]> git.tdb.fi Git - libs/math.git/commitdiff
Basic vector and matrix classes
authorMikko Rasa <tdb@tdb.fi>
Thu, 30 Aug 2012 20:41:33 +0000 (23:41 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 30 Aug 2012 20:41:33 +0000 (23:41 +0300)
Some classes are still incomplete

.gitignore [new file with mode: 0644]
Build [new file with mode: 0644]
source/dummy.cpp [new file with mode: 0644]
source/matrix.h [new file with mode: 0644]
source/matrix4.h [new file with mode: 0644]
source/squarematrix.h [new file with mode: 0644]
source/vector.h [new file with mode: 0644]
source/vector3.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e00c88d
--- /dev/null
@@ -0,0 +1,4 @@
+/.config
+/libmsplinal.so
+/msplinal.pc
+/temp
diff --git a/Build b/Build
new file mode 100644 (file)
index 0000000..51f75b9
--- /dev/null
+++ b/Build
@@ -0,0 +1,12 @@
+package "msplinal"
+{
+       library "msplinal"
+       {
+               source "source";
+               install true;
+               install_map
+               {
+                       map "source" "include/msp/linal";
+               };
+       };
+};
diff --git a/source/dummy.cpp b/source/dummy.cpp
new file mode 100644 (file)
index 0000000..dd69a99
--- /dev/null
@@ -0,0 +1,8 @@
+#include "vector.h"
+#include "vector3.h"
+#include "matrix.h"
+#include "squarematrix.h"
+#include "matrix4.h"
+
+/* This dummy file is needed to make Builder happy, and also serves as a syntax
+check by pulling in all the headers. */
diff --git a/source/matrix.h b/source/matrix.h
new file mode 100644 (file)
index 0000000..00e960d
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef MSP_LIEAL_MATMIX_H_
+#define MSP_LIEAL_MATMIX_H_
+
+#include "vector.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A general mathematical matrix.
+*/
+template<typename T, unsigned M, unsigned N>
+class Matrix
+{
+private:
+       T data[M*N];
+
+public:
+       Matrix();
+       Matrix(const T *);
+       template<typename U>
+       Matrix(const Matrix<U, M, N> &);
+       static Matrix from_columns(const Vector<T, M> *);
+       static Matrix from_rows(const Vector<T, N> *);
+
+       T &operator()(unsigned, unsigned);
+       const T &operator()(unsigned, unsigned) const;
+
+       Matrix &operator*=(T);
+       Matrix &operator/=(T);
+       Matrix &operator+=(const Matrix &);
+       Matrix &operator-=(const Matrix &);
+
+       Matrix<T, N, M> transpose() const;
+};
+
+template<typename T, unsigned M, unsigned N>
+inline T &Matrix<T, M, N>::operator()(unsigned i, unsigned j)
+{
+       return data[i+M*j];
+}
+
+template<typename T, unsigned M, unsigned N>
+inline const T &Matrix<T, M, N>::operator()(unsigned i, unsigned j) const
+{
+       return data[i+M*j];
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator*=(T s)
+{
+       for(unsigned i=0; i<M*N; ++i)
+               data[i] *= s;
+       return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator*(const Matrix<T, M, N> &m, T s)
+{
+       Matrix<T, M, N> r(m);
+       return r *= s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator*(T s, const Matrix<T, M, N> &m)
+{
+       return m*s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator/=(T s)
+{
+       for(unsigned i=0; i<M*N; ++i)
+               data[i] /= s;
+       return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator/(const Matrix<T, M, N> &m, T s)
+{
+       Matrix<T, M, N> r(m);
+       return r /= s;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator+=(const Matrix<T, M, N> &m)
+{
+       for(unsigned i=0; i<M*N; ++i)
+               data[i] += m.data[i];
+       return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator+(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
+{
+       Matrix<T, M, N> r(m1);
+       return r += m2;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> &Matrix<T, M, N>::operator-=(const Matrix<T, M, N> &m)
+{
+       for(unsigned i=0; i<M*N; ++i)
+               data[i] -= m.data[i];
+       return *this;
+}
+
+template<typename T, unsigned M, unsigned N>
+inline Matrix<T, M, N> operator-(const Matrix<T, M, N> &m1, const Matrix<T, M, N> &m2)
+{
+       Matrix<T, M, N> r(m1);
+       return r -= m2;
+}
+
+template<typename T, unsigned M, unsigned P, unsigned N>
+Matrix<T, M, N> operator*(const Matrix<T, M, P> &m1, const Matrix<T, P, N> &m2)
+{
+       Matrix<T, M, N> r;
+       for(unsigned i=0; i<M; ++i)
+               for(unsigned j=0; j<N; ++j)
+                       for(unsigned k=0; k<P; ++k)
+                               r.at(i, j) += m1(i, k)*m2(k, j);
+       return r;
+}
+
+template<typename T, unsigned M, unsigned N>
+Vector<T, M> operator*(const Matrix<T, M, N> &m, const Vector<T, N> &v)
+{
+       Vector<T, M> r;
+       for(unsigned i=0; i<M; ++i)
+               for(unsigned j=0; j<N; ++j)
+                       r[i] += m(i, j)*v[j];
+       return r;
+}
+
+template<typename T, unsigned M, unsigned N>
+Vector<T, N> operator*(const Vector<T, M> &v, const Matrix<T, M, N> &m)
+{
+       Vector<T, N> r;
+       for(unsigned j=0; j<N; ++j)
+               for(unsigned i=0; i<M; ++i)
+                       r[j] += v[i]*m.at(i, j);
+       return r;
+}
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
diff --git a/source/matrix4.h b/source/matrix4.h
new file mode 100644 (file)
index 0000000..8b89a65
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef MSP_LINAL_MATRIX4_H_
+#define MSP_LINAL_MATRIX4_H_
+
+#include "squarematrix.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A 4x4 square matrix, capable of expressing affine transformations in a
+three-dimensional vector space.
+*/
+template<typename T>
+class Matrix4: public SquareMatrix<T, 4>
+{
+};
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
diff --git a/source/squarematrix.h b/source/squarematrix.h
new file mode 100644 (file)
index 0000000..6cda86a
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef MSP_LINAL_SQUAREMATRIX_H_
+#define MSP_LINAL_SQUAREMATRIX_H_
+
+#include "matrix.h"
+
+namespace Msp {
+namespace LinAl {
+
+template<typename T, unsigned S>
+class SquareMatrix: public Matrix<T, S, S>
+{
+public:
+       SquareMatrix();
+       SquareMatrix(const T *);
+       template<typename U>
+       SquareMatrix(const Matrix<U, S, S> &);
+       static SquareMatrix identity();
+
+       SquareMatrix &operator*=(const SquareMatrix &);
+
+       void invert();
+};
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
diff --git a/source/vector.h b/source/vector.h
new file mode 100644 (file)
index 0000000..933611e
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef MSP_LINAL_VECTOR_H_
+#define MSP_LINAL_VECTOR_H_
+
+#include <algorithm>
+#include <cmath>
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A general mathematical vector.
+*/
+template<typename T, unsigned N>
+class Vector
+{
+protected:
+       T data[N];
+
+public:
+       Vector();
+       Vector(const T *d);
+       template<typename U>
+       Vector(const Vector<U, N> &v);
+
+       T &operator[](unsigned i);
+       const T &operator[](unsigned i) const;
+
+       Vector &operator*=(T);
+       Vector &operator/=(T);
+       Vector &operator+=(const Vector &);
+       Vector &operator-=(const Vector &);
+
+       T norm() const;
+       Vector &normalize();
+};
+
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector()
+{
+       std::fill(data, data+N, T());
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N>::Vector(const T *d)
+{
+       std::copy(d, d+N, data);
+}
+
+template<typename T, unsigned N>
+template<typename U>
+inline Vector<T, N>::Vector(const Vector<U, N> &v)
+{
+       std::copy(v.data, v.data+N, data);
+}
+
+template<typename T, unsigned N>
+T &Vector<T, N>::operator[](unsigned i)
+{
+       return data[i];
+}
+
+template<typename T, unsigned N>
+const T &Vector<T, N>::operator[](unsigned i) const
+{
+       return data[i];
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator*=(T s)
+{
+       for(unsigned i=0; i<N; ++i)     
+               data[i] *= s;
+       return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(const Vector<T, N> &v, T s)
+{
+       Vector<T, N> r(v);
+       return r *= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator*(T s, const Vector<T, N> &v)
+{
+       return v*s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator/=(T s)
+{
+       for(unsigned i=0; i<N; ++i)     
+               data[i] /= s;
+       return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator/(const Vector<T, N> &v, T s)
+{
+       Vector<T, N> r(v);
+       return r /= s;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator+=(const Vector<T, N> &v)
+{
+       for(unsigned i=0; i<N; ++i)     
+               data[i] += v[i];
+       return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator+(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+       Vector<T, N> r(v1);
+       return r += v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::operator-=(const Vector<T, N> &v)
+{
+       for(unsigned i=0; i<N; ++i)     
+               data[i] -= v[i];
+       return *this;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+       Vector<T, N> r(v1);
+       return r -= v2;
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> operator-(const Vector<T, N> &v)
+{
+       Vector<T, N> r(v);
+       for(unsigned i=0; i<N; ++i)
+               r[i] = -r[i];
+       return r;
+}
+
+template<typename T, unsigned N>
+inline T inner_product(const Vector<T, N> &v1, const Vector<T, N> &v2)
+{
+       T r = T();
+       for(unsigned i=0; i<N; ++i)
+               r += v1[i]*v2[i];
+       return r;
+}
+
+template<typename T, unsigned N>
+inline T Vector<T, N>::norm() const
+{
+       return sqrt(inner_product(*this, *this));
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> &Vector<T, N>::normalize()
+{
+       return *this /= norm();
+}
+
+template<typename T, unsigned N>
+inline Vector<T, N> normalize(const Vector<T, N> &v)
+{
+       Vector<T, N> r(v);
+       return r.normalize();
+}
+
+} // namespace LinAl
+} // namespace Msp
+
+#endif
diff --git a/source/vector3.h b/source/vector3.h
new file mode 100644 (file)
index 0000000..90a5ff5
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef MSP_LINAL_VECTOR3_H_
+#define MSP_LINAL_VECTOR3_H_
+
+#include "vector.h"
+
+namespace Msp {
+namespace LinAl {
+
+/**
+A three-dimensional vector, applicable for Euclidean space.
+*/
+template<typename T>
+class Vector3: public Vector<T, 3>
+{
+public:
+       Vector3() { }
+       Vector3(const T *);
+       Vector3(T, T, T);
+       template<typename U>
+       Vector3(const Vector<U, 3> &);
+};
+
+template<typename T>
+inline Vector3<T>::Vector3(const T *d):
+       Vector<T, 3>(d)
+{ }
+
+template<typename T>
+inline Vector3<T>::Vector3(T x, T y, T z)
+{
+       this->data[0] = x;
+       this->data[1] = y;
+       this->data[2] = z;
+}
+
+template<typename T>
+template<typename U>
+inline Vector3<T>::Vector3(const Vector<U, 3> &v):
+       Vector<T, 3>(v)
+{ }
+
+template<typename T>
+inline T dot(const Vector3<T> &v1, const Vector3<T> &v2)
+{
+       return inner_product(v1, v2);
+}
+
+template<typename T>
+inline Vector3<T> cross(const Vector3<T> &v1, const Vector3<T> &v2)
+{
+       return Vector3<T>(v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]);
+}
+
+} // namespace LinAl
+} // namespace LinAl
+
+#endif