Files
geant4/source/analysis/g4tools/include/tools/lina/vec4
T
2019-12-06 15:12:28 +01:00

289 lines
6.8 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_vec4
#define tools_vec4
#include <cstddef> //size_t
#ifdef TOOLS_MEM
#include "../mem"
#endif
namespace tools {
template <class T>
class vec4 {
#ifdef TOOLS_MEM
public:
static const std::string& s_class() {
static const std::string s_v("tools::vec4");
return s_v;
}
#endif
protected:
static T zero() {return T();}
static T minus_one() {return T(-1);}
public:
typedef T elem_t;
unsigned int dimension() const {return 4;}
public:
vec4(){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_data[0] = T();
m_data[1] = T();
m_data[2] = T();
m_data[3] = T();
}
vec4(const T a_vec[4]) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_data[0] = a_vec[0];
m_data[1] = a_vec[1];
m_data[2] = a_vec[2];
m_data[3] = a_vec[3];
}
vec4(const T& a0,const T& a1,const T& a2,const T& a3
#ifdef TOOLS_MEM
,bool a_inc = true
#endif
) {
#ifdef TOOLS_MEM
if(a_inc) mem::increment(s_class().c_str());
#endif
m_data[0] = a0;
m_data[1] = a1;
m_data[2] = a2;
m_data[3] = a3;
}
virtual ~vec4() {
#ifdef TOOLS_MEM
mem::decrement(s_class().c_str());
#endif
}
public:
vec4(const vec4& a_from){
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
#endif
m_data[0] = a_from.m_data[0];
m_data[1] = a_from.m_data[1];
m_data[2] = a_from.m_data[2];
m_data[3] = a_from.m_data[3];
}
vec4& operator=(const vec4& a_from) {
m_data[0] = a_from.m_data[0];
m_data[1] = a_from.m_data[1];
m_data[2] = a_from.m_data[2];
m_data[3] = a_from.m_data[3];
return *this;
}
public:
const T& v0() const { return m_data[0];}
const T& v1() const { return m_data[1];}
const T& v2() const { return m_data[2];}
const T& v3() const { return m_data[3];}
void v0(const T& a_value) { m_data[0] = a_value;}
void v1(const T& a_value) { m_data[1] = a_value;}
void v2(const T& a_value) { m_data[2] = a_value;}
void v3(const T& a_value) { m_data[3] = a_value;}
const T& x() const { return m_data[0];}
const T& y() const { return m_data[1];}
const T& z() const { return m_data[2];}
const T& t() const { return m_data[3];}
void set_value(const T& a0,const T& a1,const T& a2,const T& a3) {
m_data[0] = a0;
m_data[1] = a1;
m_data[2] = a2;
m_data[3] = a3;
}
void set_value(const T aV[4]) {
m_data[0] = aV[0];
m_data[1] = aV[1];
m_data[2] = aV[2];
m_data[3] = aV[3];
}
void value(T& a0,T& a1,T& a2,T& a3) const {
a0 = m_data[0];
a1 = m_data[1];
a2 = m_data[2];
a3 = m_data[3];
}
bool set_value(unsigned int a_index,const T& a_value) {
if(a_index>=4) return false;
m_data[a_index] = a_value;
return true;
}
T length(T(*a_sqrt)(T)) const {
return a_sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]+m_data[3]*m_data[3]);
}
T normalize(T(*a_sqrt)(T)) {
T norme = length(a_sqrt);
if(norme==T()) return T();
divide(norme);
return norme;
}
bool equal(const vec4& a_vec) const {
if(m_data[0]!=a_vec.m_data[0]) return false;
if(m_data[1]!=a_vec.m_data[1]) return false;
if(m_data[2]!=a_vec.m_data[2]) return false;
if(m_data[3]!=a_vec.m_data[3]) return false;
return true;
}
bool equal(const vec4& a_vec,const T& a_epsil) const {
T* tp = (T*)m_data;
T* ap = (T*)a_vec.m_data;
for(unsigned int i=0;i<4;i++,tp++,ap++) {
T diff = (*tp) - (*ap);
if(diff<zero()) diff *= minus_one();
if(diff>=a_epsil) return false;
}
return true;
}
bool is_proportional(const vec4& a_vec,T& a_factor) const {
// If true, then : a_vec = a_factor * this.
a_factor = zero();
bool first = true;
T* tp = (T*)m_data;
T* ap = (T*)a_vec.m_data;
for(unsigned int i=0;i<4;i++,tp++,ap++) {
if( ((*tp)==zero()) && ((*ap)==zero())) {
continue;
} else if( ((*tp)!=zero()) && ((*ap)==zero())) {
return false;
} else if( ((*tp)==zero()) && ((*ap)!=zero())) {
return false;
} else {
if(first) {
a_factor = (*ap)/(*tp);
first = false;
} else {
if((*ap)!=(*tp)*a_factor) return false;
}
}
}
return true;
}
void multiply(const T& a_T) {
m_data[0] *= a_T;
m_data[1] *= a_T;
m_data[2] *= a_T;
m_data[3] *= a_T;
}
bool divide(const T& a_T) {
if(a_T==T()) return false;
m_data[0] /= a_T;
m_data[1] /= a_T;
m_data[2] /= a_T;
m_data[3] /= a_T;
return true;
}
void add(const vec4& a_v) {
m_data[0] += a_v.m_data[0];
m_data[1] += a_v.m_data[1];
m_data[2] += a_v.m_data[2];
m_data[3] += a_v.m_data[3];
}
void add(const T& a0,const T& a1,const T& a2,const T& a3) {
m_data[0] += a0;
m_data[1] += a1;
m_data[2] += a2;
m_data[3] += a3;
}
void subtract(const vec4& a_v) {
m_data[0] -= a_v.m_data[0];
m_data[1] -= a_v.m_data[1];
m_data[2] -= a_v.m_data[2];
m_data[3] -= a_v.m_data[3];
}
void subtract(const T& a0,const T& a1,const T& a2,const T& a3) {
m_data[0] -= a0;
m_data[1] -= a1;
m_data[2] -= a2;
m_data[3] -= a3;
}
public: //operators
T& operator[](size_t a_index) {
//WARNING : no check on a_index.
return m_data[a_index];
}
const T& operator[](size_t a_index) const {
//WARNING : no check on a_index.
return m_data[a_index];
}
vec4 operator+(const vec4& a_v) const {
return vec4(m_data[0]+a_v.m_data[0],
m_data[1]+a_v.m_data[1],
m_data[2]+a_v.m_data[2],
m_data[3]+a_v.m_data[3]);
}
vec4 operator-(const vec4& a_v) const {
return vec4(m_data[0]-a_v.m_data[0],
m_data[1]-a_v.m_data[1],
m_data[2]-a_v.m_data[2],
m_data[3]-a_v.m_data[3]);
}
vec4 operator*(const T& a_v) const {
return vec4(m_data[0]*a_v,
m_data[1]*a_v,
m_data[2]*a_v,
m_data[3]*a_v);
}
bool operator==(const vec4& a_v) const {return equal(a_v);}
bool operator!=(const vec4& a_v) const {return !operator==(a_v);}
public: //for inlib/sg/sf_vec
typedef unsigned int size_type;
size_type size() const {return 4;}
const T* data() const {return m_data;}
protected:
T m_data[4];
private:static void check_instantiation() {vec4<float> v;}
};
//for sf, mf :
template <class T>
inline const T* get_data(const vec4<T>& a_v) {return a_v.data();}
}
#include <ostream>
namespace tools {
// for sf_vec::dump().
template <class T>
inline std::ostream& operator<<(std::ostream& a_out,const vec4<T>& a_this){
a_out << "x = " << a_this.v0()
<< ",y = " << a_this.v1()
<< ",z = " << a_this.v2()
<< ",t = " << a_this.v3();
return a_out;
}
}
#endif