Skip to content

Commit

Permalink
c++14 facelift
Browse files Browse the repository at this point in the history
  • Loading branch information
ssloy committed Aug 25, 2020
1 parent 2f3c086 commit 87c7dc9
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 300 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ endfunction()
enable_cxx_compiler_flag_if_supported("-Wall")
enable_cxx_compiler_flag_if_supported("-Wextra")
enable_cxx_compiler_flag_if_supported("-pedantic")
enable_cxx_compiler_flag_if_supported("-std=c++11")
enable_cxx_compiler_flag_if_supported("-std=c++14")
enable_cxx_compiler_flag_if_supported("-O3")
enable_cxx_compiler_flag_if_supported("-fopenmp")

Expand Down
7 changes: 3 additions & 4 deletions geometry.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "geometry.h"

template <> template <> vec<3,int> ::vec(const vec<3,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)),z(int(v.z+.5f)) {}
template <> template <> vec<3,float>::vec(const vec<3,int> &v) : x(v.x),y(v.y),z(v.z) {}
template <> template <> vec<2,int> ::vec(const vec<2,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)) {}
template <> template <> vec<2,float>::vec(const vec<2,int> &v) : x(v.x),y(v.y) {}
vec3 cross(const vec3 &v1, const vec3 &v2) {
return vec<3>{v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x};
}

289 changes: 153 additions & 136 deletions geometry.h
Original file line number Diff line number Diff line change
@@ -1,221 +1,238 @@
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__

#include <cmath>
#include <vector>
#include <cassert>
#include <iostream>

template<size_t DimCols,size_t DimRows,typename T> class mat;

template <size_t DIM, typename T> struct vec {
vec() { for (size_t i=DIM; i--; data_[i] = T()); }
T& operator[](const size_t i) { assert(i<DIM); return data_[i]; }
const T& operator[](const size_t i) const { assert(i<DIM); return data_[i]; }
private:
T data_[DIM];
};

/////////////////////////////////////////////////////////////////////////////////

template <typename T> struct vec<2,T> {
vec() : x(T()), y(T()) {}
vec(T X, T Y) : x(X), y(Y) {}
template <class U> vec<2,T>(const vec<2,U> &v);
T& operator[](const size_t i) { assert(i<2); return i<=0 ? x : y; }
const T& operator[](const size_t i) const { assert(i<2); return i<=0 ? x : y; }

T x,y;
template<int n> struct vec {
vec() = default;
double & operator[](const int i) { assert(i>=0 && i<n); return data[i]; }
double operator[](const int i) const { assert(i>=0 && i<n); return data[i]; }
double norm2() const { return (*this)*(*this) ; }
double norm() const { return std::sqrt(norm2()); }
double data[n] = {0};
};

/////////////////////////////////////////////////////////////////////////////////

template <typename T> struct vec<3,T> {
vec() : x(T()), y(T()), z(T()) {}
vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {}
template <class U> vec<3,T>(const vec<3,U> &v);
T& operator[](const size_t i) { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
const T& operator[](const size_t i) const { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
float norm() { return std::sqrt(x*x+y*y+z*z); }
vec<3,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; }

T x,y,z;
};

/////////////////////////////////////////////////////////////////////////////////

template<size_t DIM,typename T> T operator*(const vec<DIM,T>& lhs, const vec<DIM,T>& rhs) {
T ret = T();
for (size_t i=DIM; i--; ret+=lhs[i]*rhs[i]);
template<int n> double operator*(const vec<n>& lhs, const vec<n>& rhs) {
double ret = 0;
for (int i=n; i--; ret+=lhs[i]*rhs[i]);
return ret;
}


template<size_t DIM,typename T>vec<DIM,T> operator+(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
for (size_t i=DIM; i--; lhs[i]+=rhs[i]);
return lhs;
template<int n> vec<n> operator+(const vec<n>& lhs, const vec<n>& rhs) {
vec<n> ret = lhs;
for (int i=n; i--; ret[i]+=rhs[i]);
return ret;
}

template<size_t DIM,typename T>vec<DIM,T> operator-(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
for (size_t i=DIM; i--; lhs[i]-=rhs[i]);
return lhs;
template<int n> vec<n> operator-(const vec<n>& lhs, const vec<n>& rhs) {
vec<n> ret = lhs;
for (int i=n; i--; ret[i]-=rhs[i]);
return ret;
}

template<size_t DIM,typename T,typename U> vec<DIM,T> operator*(vec<DIM,T> lhs, const U& rhs) {
for (size_t i=DIM; i--; lhs[i]*=rhs);
return lhs;
template<int n> vec<n> operator*(const double& rhs, const vec<n> &lhs) {
vec<n> ret = lhs;
for (int i=n; i--; ret[i]*=rhs);
return ret;
}

template<size_t DIM,typename T,typename U> vec<DIM,T> operator/(vec<DIM,T> lhs, const U& rhs) {
for (size_t i=DIM; i--; lhs[i]/=rhs);
return lhs;
template<int n> vec<n> operator*(const vec<n>& lhs, const double& rhs) {
vec<n> ret = lhs;
for (int i=n; i--; ret[i]*=rhs);
return ret;
}

template<size_t LEN,size_t DIM,typename T> vec<LEN,T> embed(const vec<DIM,T> &v, T fill=1) {
vec<LEN,T> ret;
for (size_t i=LEN; i--; ret[i]=(i<DIM?v[i]:fill));
template<int n> vec<n> operator/(const vec<n>& lhs, const double& rhs) {
vec<n> ret = lhs;
for (int i=n; i--; ret[i]/=rhs);
return ret;
}

template<size_t LEN,size_t DIM, typename T> vec<LEN,T> proj(const vec<DIM,T> &v) {
vec<LEN,T> ret;
for (size_t i=LEN; i--; ret[i]=v[i]);
template<int n1,int n2> vec<n1> embed(const vec<n2> &v, double fill=1) {
vec<n1> ret;
for (int i=n1; i--; ret[i]=(i<n2?v[i]:fill));
return ret;
}

template <typename T> vec<3,T> cross(vec<3,T> v1, vec<3,T> v2) {
return vec<3,T>(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
template<int n1,int n2> vec<n1> proj(const vec<n2> &v) {
vec<n1> ret;
for (int i=n1; i--; ret[i]=v[i]);
return ret;
}

template <size_t DIM, typename T> std::ostream& operator<<(std::ostream& out, vec<DIM,T>& v) {
for(unsigned int i=0; i<DIM; i++) {
out << v[i] << " " ;
}
return out ;

template<int n> std::ostream& operator<<(std::ostream& out, const vec<n>& v) {
for (int i=0; i<n; i++) out << v[i] << " ";
return out;
}

/////////////////////////////////////////////////////////////////////////////////

template<size_t DIM,typename T> struct dt {
static T det(const mat<DIM,DIM,T>& src) {
T ret=0;
for (size_t i=DIM; i--; ret += src[0][i]*src.cofactor(0,i));
return ret;
}
template<> struct vec<2> {
vec() = default;
vec(double X, double Y) : x(X), y(Y) {}
double& operator[](const int i) { assert(i>=0 && i<2); return i==0 ? x : y; }
double operator[](const int i) const { assert(i>=0 && i<2); return i==0 ? x : y; }
double norm2() const { return (*this)*(*this) ; }
double norm() const { return std::sqrt(norm2()); }
vec & normalize() { *this = (*this)/norm(); return *this; }

double x{}, y{};
};

template<typename T> struct dt<1,T> {
static T det(const mat<1,1,T>& src) {
return src[0][0];
}
/////////////////////////////////////////////////////////////////////////////////

template<> struct vec<3> {
vec() = default;
vec(double X, double Y, double Z) : x(X), y(Y), z(Z) {}
double& operator[](const int i) { assert(i>=0 && i<3); return i==0 ? x : (1==i ? y : z); }
double operator[](const int i) const { assert(i>=0 && i<3); return i==0 ? x : (1==i ? y : z); }
double norm2() const { return (*this)*(*this) ; }
double norm() const { return std::sqrt(norm2()); }
vec & normalize() { *this = (*this)/norm(); return *this; }

double x{}, y{}, z{};
};

/////////////////////////////////////////////////////////////////////////////////

template<size_t DimRows,size_t DimCols,typename T> class mat {
vec<DimCols,T> rows[DimRows];
public:
mat() {}
template<int n> struct dt;

vec<DimCols,T>& operator[] (const size_t idx) {
assert(idx<DimRows);
return rows[idx];
}
template<int nrows,int ncols> struct mat {
vec<ncols> rows[nrows] = {{}};

const vec<DimCols,T>& operator[] (const size_t idx) const {
assert(idx<DimRows);
return rows[idx];
}
mat() = default;
vec<ncols>& operator[] (const int idx) { assert(idx>=0 && idx<nrows); return rows[idx]; }
const vec<ncols>& operator[] (const int idx) const { assert(idx>=0 && idx<nrows); return rows[idx]; }

vec<DimRows,T> col(const size_t idx) const {
assert(idx<DimCols);
vec<DimRows,T> ret;
for (size_t i=DimRows; i--; ret[i]=rows[i][idx]);
vec<nrows> col(const int idx) const {
assert(idx>=0 && idx<ncols);
vec<nrows> ret;
for (int i=nrows; i--; ret[i]=rows[i][idx]);
return ret;
}

void set_col(size_t idx, vec<DimRows,T> v) {
assert(idx<DimCols);
for (size_t i=DimRows; i--; rows[i][idx]=v[i]);
void set_col(const int idx, const vec<nrows> &v) {
assert(idx>=0 && idx<ncols);
for (int i=nrows; i--; rows[i][idx]=v[i]);
}

static mat<DimRows,DimCols,T> identity() {
mat<DimRows,DimCols,T> ret;
for (size_t i=DimRows; i--; )
for (size_t j=DimCols;j--; ret[i][j]=(i==j));
static mat<nrows,ncols> identity() {
mat<nrows,ncols> ret;
for (int i=nrows; i--; )
for (int j=ncols;j--; ret[i][j]=(i==j));
return ret;
}

T det() const {
return dt<DimCols,T>::det(*this);
double det() const {
return dt<ncols>::det(*this);
}

mat<DimRows-1,DimCols-1,T> get_minor(size_t row, size_t col) const {
mat<DimRows-1,DimCols-1,T> ret;
for (size_t i=DimRows-1; i--; )
for (size_t j=DimCols-1;j--; ret[i][j]=rows[i<row?i:i+1][j<col?j:j+1]);
mat<nrows-1,ncols-1> get_minor(const int row, const int col) const {
mat<nrows-1,ncols-1> ret;
for (int i=nrows-1; i--; )
for (int j=ncols-1;j--; ret[i][j]=rows[i<row?i:i+1][j<col?j:j+1]);
return ret;
}

T cofactor(size_t row, size_t col) const {
double cofactor(const int row, const int col) const {
return get_minor(row,col).det()*((row+col)%2 ? -1 : 1);
}

mat<DimRows,DimCols,T> adjugate() const {
mat<DimRows,DimCols,T> ret;
for (size_t i=DimRows; i--; )
for (size_t j=DimCols; j--; ret[i][j]=cofactor(i,j));
mat<nrows,ncols> adjugate() const {
mat<nrows,ncols> ret;
for (int i=nrows; i--; )
for (int j=ncols; j--; ret[i][j]=cofactor(i,j));
return ret;
}

mat<DimRows,DimCols,T> invert_transpose() {
mat<DimRows,DimCols,T> ret = adjugate();
T tmp = ret[0]*rows[0];
return ret/tmp;
mat<nrows,ncols> invert_transpose() const {
mat<nrows,ncols> ret = adjugate();
return ret/(ret[0]*rows[0]);
}

mat<DimRows,DimCols,T> invert() {
mat<nrows,ncols> invert() const {
return invert_transpose().transpose();
}

mat<DimCols,DimRows,T> transpose() {
mat<DimCols,DimRows,T> ret;
for (size_t i=DimCols; i--; ret[i]=this->col(i));
mat<ncols,nrows> transpose() const {
mat<ncols,nrows> ret;
for (int i=ncols; i--; ret[i]=this->col(i));
return ret;
}
};

/////////////////////////////////////////////////////////////////////////////////

template<size_t DimRows,size_t DimCols,typename T> vec<DimRows,T> operator*(const mat<DimRows,DimCols,T>& lhs, const vec<DimCols,T>& rhs) {
vec<DimRows,T> ret;
for (size_t i=DimRows; i--; ret[i]=lhs[i]*rhs);
template<int nrows,int ncols> vec<nrows> operator*(const mat<nrows,ncols>& lhs, const vec<ncols>& rhs) {
vec<nrows> ret;
for (int i=nrows; i--; ret[i]=lhs[i]*rhs);
return ret;
}

template<size_t R1,size_t C1,size_t C2,typename T>mat<R1,C2,T> operator*(const mat<R1,C1,T>& lhs, const mat<C1,C2,T>& rhs) {
mat<R1,C2,T> result;
for (size_t i=R1; i--; )
for (size_t j=C2; j--; result[i][j]=lhs[i]*rhs.col(j));
template<int R1,int C1,int C2>mat<R1,C2> operator*(const mat<R1,C1>& lhs, const mat<C1,C2>& rhs) {
mat<R1,C2> result;
for (int i=R1; i--; )
for (int j=C2; j--; result[i][j]=lhs[i]*rhs.col(j));
return result;
}

template<int nrows,int ncols>mat<nrows,ncols> operator*(const mat<nrows,ncols>& lhs, const double& val) {
mat<nrows,ncols> result;
for (int i=nrows; i--; result[i] = lhs[i]*val);
return result;
}

template<size_t DimRows,size_t DimCols,typename T>mat<DimCols,DimRows,T> operator/(mat<DimRows,DimCols,T> lhs, const T& rhs) {
for (size_t i=DimRows; i--; lhs[i]=lhs[i]/rhs);
return lhs;
template<int nrows,int ncols>mat<nrows,ncols> operator/(const mat<nrows,ncols>& lhs, const double& val) {
mat<nrows,ncols> result;
for (int i=nrows; i--; result[i] = lhs[i]/val);
return result;
}

template <size_t DimRows,size_t DimCols,class T> std::ostream& operator<<(std::ostream& out, mat<DimRows,DimCols,T>& m) {
for (size_t i=0; i<DimRows; i++) out << m[i] << std::endl;
template<int nrows,int ncols>mat<nrows,ncols> operator+(const mat<nrows,ncols>& lhs, const mat<nrows,ncols>& rhs) {
mat<nrows,ncols> result;
for (int i=nrows; i--; )
for (int j=ncols; j--; result[i][j]=lhs[i][j]+rhs[i][j]);
return result;
}

template<int nrows,int ncols>mat<nrows,ncols> operator-(const mat<nrows,ncols>& lhs, const mat<nrows,ncols>& rhs) {
mat<nrows,ncols> result;
for (int i=nrows; i--; )
for (int j=ncols; j--; result[i][j]=lhs[i][j]-rhs[i][j]);
return result;
}

template<int nrows,int ncols> std::ostream& operator<<(std::ostream& out, const mat<nrows,ncols>& m) {
for (int i=0; i<nrows; i++) out << m[i] << std::endl;
return out;
}

/////////////////////////////////////////////////////////////////////////////////

typedef vec<2, float> Vec2f;
typedef vec<2, int> Vec2i;
typedef vec<3, float> Vec3f;
typedef vec<3, int> Vec3i;
typedef vec<4, float> Vec4f;
typedef mat<4,4,float> Matrix;
template<int n> struct dt {
static double det(const mat<n,n>& src) {
double ret = 0;
for (int i=n; i--; ret += src[0][i]*src.cofactor(0,i));
return ret;
}
};

template<> struct dt<1> {
static double det(const mat<1,1>& src) {
return src[0][0];
}
};

/////////////////////////////////////////////////////////////////////////////////

typedef vec<2> vec2;
typedef vec<3> vec3;
typedef vec<4> vec4;
typedef mat<4,4> mat44;
vec3 cross(const vec3 &v1, const vec3 &v2);

#endif //__GEOMETRY_H__

Loading

0 comments on commit 87c7dc9

Please sign in to comment.