Import Geant4 10.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-12-09 12:35:28 +01:00
parent 4ec577e5c4
commit a3452e42ac
3514 changed files with 210500 additions and 89628 deletions
@@ -47,6 +47,10 @@ inline void vec_sub(const T* a_1,const T* a_2,T* a_res,unsigned int a_number) {
}
*/
#include "eqT"
#include <cstddef> //size_t
// common code to class mat and nmat.
#define TOOLS_MATCOM \
@@ -101,6 +105,32 @@ public:\
void set_random(RANDOM& a_random) {\
for(unsigned int i=0;i<dim2();i++) m_vec[i] = a_random.shoot();\
}\
template <class RANDOM>\
void set_symmetric_random(RANDOM& a_random) {\
unsigned int _D = dimension();\
{for(unsigned int r=0;r<_D;r++) set_value(r,r,a_random.shoot());}\
T rd;\
{for(unsigned int r=0;r<_D;r++) {\
for(unsigned int c=(r+1);c<_D;c++) {\
rd = a_random.shoot();\
set_value(r,c,rd);\
set_value(c,r,rd);\
}\
}}\
}\
template <class RANDOM>\
void set_antisymmetric_random(RANDOM& a_random) {\
unsigned int _D = dimension();\
{for(unsigned int r=0;r<_D;r++) set_value(r,r,zero());}\
T rd;\
{for(unsigned int r=0;r<_D;r++) {\
for(unsigned int c=(r+1);c<_D;c++) {\
rd = a_random.shoot();\
set_value(r,c,rd);\
set_value(c,r,minus_one()*rd);\
}\
}}\
}\
public:\
template <class VEC>\
bool mul_vec(VEC& a_vec,T a_tmp[]) const {\
@@ -122,6 +152,25 @@ public:\
delete [] res;\
return status;\
}\
\
bool mul_array(T a_vec[],T a_tmp[]) const {\
/* a_vec = this *= a_vec */\
unsigned int _dim = dimension();\
T* pos = a_tmp;\
for(unsigned int r=0;r<_dim;r++,pos++) {\
*pos = T();\
for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_vec[c];\
}\
{for(unsigned int i=0;i<_dim;i++) a_vec[i] = a_tmp[i];}\
return true;\
}\
bool mul_array(T a_vec[]) const {\
T* res = new T[dimension()];\
bool status = mul_array(a_vec,res);\
delete [] res;\
return status;\
}\
\
void mul_mtx(const TOOLS_MAT_CLASS& a_m) {\
_mul_mtx(a_m.m_vec);\
}\
@@ -151,6 +200,18 @@ public:\
}\
return true;\
}\
\
template <class PREC>\
bool equal_prec(const TOOLS_MAT_CLASS& a_m,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
if(&a_m==this) return true;\
T* tp = (T*)m_vec;\
T* mp = (T*)a_m.m_vec;\
for(unsigned int i=0;i<dim2();i++,tp++,mp++) {\
T diff = (*tp) - (*mp);\
if(a_fabs(diff)>=a_prec) return false;\
}\
return true;\
}\
\
void mx_diff(const TOOLS_MAT_CLASS& a_m,T& a_mx_diff) const {\
T* tp = (T*)m_vec;\
@@ -191,6 +252,49 @@ public:\
}\
return true;\
}\
\
public:\
template <class PREC>\
bool is_proportional_prec(const TOOLS_MAT_CLASS& a_right,const PREC& a_prec,PREC(*a_fabs)(const T&),T& a_factor) const {\
/* If true, then : a_right = a_factor * this.*/\
if(this==&a_right) {a_factor=T(1);return true;}\
T _zero = zero();\
a_factor = _zero;\
if(dimension()!=a_right.dimension()) return false;\
T* lp = (T*)m_vec;\
T* rp = (T*)a_right.m_vec;\
bool first = true;\
size_t _data_size = data_size();\
for(size_t i=0;i<_data_size;i++,lp++,rp++) {\
if( numbers_are_equals(*lp,_zero,a_prec,a_fabs) && numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
continue;\
} else if( !numbers_are_equals(*lp,_zero,a_prec,a_fabs) && numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
return false;\
} else if( numbers_are_equals(*lp,_zero,a_prec,a_fabs) && !numbers_are_equals(*rp,_zero,a_prec,a_fabs) ) {\
return false;\
} else {\
if(first) {\
a_factor = (*rp)/(*lp);\
first = false;\
} else {\
if(!numbers_are_equals((*lp)*a_factor,*rp,a_prec,a_fabs)) return false;\
}\
}\
}\
return true;\
}\
\
template <class PREC>\
bool is_diagonal_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
T _zero = zero();\
unsigned int _D = dimension();\
for(unsigned int r=0;r<_D;r++) {\
for(unsigned int c=0;c<_D;c++) {\
if(c!=r) {if(!numbers_are_equals(value(r,c),_zero,a_prec,a_fabs)) return false;}\
}\
}\
return true;\
}\
\
const T* data() const {return m_vec;}\
unsigned int size() const {return dim2();}\
@@ -228,6 +332,18 @@ public:\
}\
return true;\
}\
\
template <class PREC>\
bool is_symmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
unsigned int _D = dimension();\
for(unsigned int r=0;r<_D;r++) {\
for(unsigned int c=(r+1);c<_D;c++) {\
T diff = value(r,c)-value(c,r);\
if(a_fabs(diff)>=a_prec) return false;\
}\
}\
return true;\
}\
\
bool is_antisymmetric() const {\
unsigned int _D = dimension();\
@@ -479,11 +595,11 @@ public: /*operators*/\
return m_vec[a_r + a_c * dimension()];\
}\
\
T& operator[](unsigned int a_index) { /*for inlib/sg/sf_vec*/\
T& operator[](size_t a_index) { /*for inlib/sg/sf_vec*/\
/*WARNING : no check on a_index.*/\
return m_vec[a_index];\
}\
const T& operator[](unsigned int a_index) const {\
const T& operator[](size_t a_index) const {\
/*WARNING : no check on a_index.*/\
return m_vec[a_index];\
}\
@@ -16,6 +16,7 @@ class box3 {
protected:
typedef typename VEC3::elem_t T_t;
//static T_t num_max() {return std::numeric_limits<T_t>::max();} //max is a forever pain on Windows.
static T_t zero() {return T_t();}
protected:
box3(){
//make_empty();
@@ -120,6 +121,29 @@ public:
}
}
bool get_cube_size(T_t& a_dx,T_t& a_dy,T_t& a_dz,T_t(*a_sqrt)(T_t)) const {
if(!get_size(a_dx,a_dy,a_dz)) return false;
if((a_dx<=zero())&&(a_dy<=zero())&&(a_dz<=zero())) return false;
if((a_dx<=zero())&&(a_dy<=zero())) { //dz not 0 :
a_dx = T_t(0.1)*a_dz;
a_dy = T_t(0.1)*a_dz;
} else if((a_dy<=zero())&&(a_dz<=zero())) { //dx not 0 :
a_dy = T_t(0.1)*a_dx;
a_dz = T_t(0.1)*a_dx;
} else if((a_dz<=zero())&&(a_dx<=zero())) { //dy not 0 :
a_dz = T_t(0.1)*a_dy;
a_dx = T_t(0.1)*a_dy;
} else if(a_dx<=zero()) { //dy,dz not 0 :
a_dx = T_t(0.1)*a_sqrt(a_dy*a_dy+a_dz*a_dz);
} else if(a_dy<=zero()) { //dx,dz not 0 :
a_dy = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dz*a_dz);
} else if(a_dz<=zero()) { //dx,dy not 0 :
a_dz = T_t(0.1)*a_sqrt(a_dx*a_dx+a_dy*a_dy);
}
return true;
}
//NOTE : print is a Python keyword.
void dump(std::ostream& a_out) {
T_t dx,dy,dz;
@@ -27,6 +27,9 @@ public:
m_min.set_value( num_max(), num_max(), num_max());
m_max.set_value(-num_max(), -num_max(), -num_max());
}
bool get_cube_size(float& a_dx,float& a_dy,float& a_dz) const {
return parent::get_cube_size(a_dx,a_dy,a_dz,::sqrtf);
}
};
}
@@ -0,0 +1,18 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_eqT
#define tools_eqT
namespace tools {
template <class NUMBER,class PREC>
inline bool numbers_are_equals(const NUMBER& a_left,const NUMBER& a_right,const PREC& a_prec,PREC(*a_fabs)(const NUMBER&)) {
NUMBER diff = a_left - a_right;
if(a_fabs(diff)>=a_prec) return false;
return true;
}
}
#endif
@@ -0,0 +1,94 @@
// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_geom2
#define tools_geom2
#include <vector>
#include <cstddef>
namespace tools {
template <class VEC2>
inline double is_left(const VEC2& P0,const VEC2& P1,const VEC2& P2){
return ( (P1.v0() - P0.v0()) * (P2.v1() - P0.v1())
- (P2.v0() - P0.v0()) * (P1.v1() - P0.v1()) );
}
template <class VEC2>
inline bool is_inside(const VEC2& a_P,const std::vector<VEC2>& a_V) {
// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
// From :
// http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
// Copyright 2001, softSurfer (www.softsurfer.com)
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
size_t n = a_V.size()-1;
int wn = 0; // the winding number counter
// loop through all edges of the polygon
for (size_t i=0; i<n; i++) { // edge from V[i] to V[i+1]
if (a_V[i].v1() <= a_P.v1()) { // start y <= P[1]
if (a_V[i+1].v1() > a_P.v1()) // an upward crossing
if (is_left( a_V[i], a_V[i+1], a_P) > 0) // P left of edge
++wn; // have a valid up intersect
} else { // start y > P[1] (no test needed)
if (a_V[i+1].v1() <= a_P.v1()) // a downward crossing
if (is_left( a_V[i], a_V[i+1], a_P) < 0) // P right of edge
--wn; // have a valid down intersect
}
}
return ((wn!=0)?true:false);
}
// the same done with std::pair.
template <class T>
inline double is_left(const std::pair<T,T>& P0,const std::pair<T,T>& P1,const std::pair<T,T>& P2){
return ( (P1.first - P0.first) * (P2.second - P0.second)
- (P2.first - P0.first) * (P1.second - P0.second) );
}
template <class T>
inline bool inside(const std::pair<T,T>& a_P,const std::vector< std::pair<T,T> >& a_V) {
// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
// From :
// http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
// Copyright 2001, softSurfer (www.softsurfer.com)
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
size_t n = a_V.size()-1;
int wn = 0; // the winding number counter
// loop through all edges of the polygon
for (size_t i=0; i<n; i++) { // edge from V[i] to V[i+1]
if (a_V[i].second <= a_P.second) { // start y <= P[1]
if (a_V[i+1].second > a_P.second) // an upward crossing
if (is_left( a_V[i], a_V[i+1], a_P) > 0) // P left of edge
++wn; // have a valid up intersect
} else { // start y > P[1] (no test needed)
if (a_V[i+1].second <= a_P.second) // a downward crossing
if (is_left( a_V[i], a_V[i+1], a_P) < 0) // P right of edge
--wn; // have a valid down intersect
}
}
return ((wn!=0)?true:false);
}
}
#endif
@@ -6,6 +6,7 @@
#include "line"
#include "plane"
#include "vec3"
namespace tools {
+18 -18
View File
@@ -4,18 +4,18 @@
#ifndef tools_line
#define tools_line
#include "vec3"
namespace tools {
// Parametric description:
// l(t) = pos + t * dir
template <class T>
template <class VEC3>
class line {
protected:
typedef typename VEC3::elem_t T;
public:
line(){}
line(const vec3<T>& a_p0,const vec3<T>& a_p1) {
line(const VEC3& a_p0,const VEC3& a_p1) {
// Construct a line from two points lying on the line. If you
// want to construct a line from a position and a direction, use
// line(p, p + d).
@@ -45,7 +45,7 @@ public:
return *this;
}
public:
void set_value(const vec3<T>& a_p0,const vec3<T>& a_p1) {
void set_value(const VEC3& a_p0,const VEC3& a_p1) {
m_pos = a_p0;
m_dir = a_p0;
m_dir.multiply(-1);
@@ -59,11 +59,11 @@ public:
m_dir.normalize();
}
const vec3<T>& position() const {return m_pos;}
const vec3<T>& direction() const {return m_dir;}
const VEC3& position() const {return m_pos;}
const VEC3& direction() const {return m_dir;}
/* not tested :
vec3<T> closest_point(const vec3<T>& a_point) const {
VEC3 closest_point(const VEC3& a_point) const {
//from coin3d/SbLine.cpp.
//
@@ -81,7 +81,7 @@ public:
bool closest_points(const line<T>& a_line,
vec3<T>& a_on_this,vec3<T>& a_on_line) const {
VEC3& a_on_this,VEC3& a_on_line) const {
//from coin3d/SbLine.cpp.
//WARNING : if ret false, a_on_this, a_on_line not set.
@@ -91,11 +91,11 @@ public:
if(a_line.m_dir == m_dir) return false;
if(a_line.m_dir == T(-1)*m_dir) return false;
vec3<T> P0 = m_pos;
vec3<T> P1 = a_line.m_pos;
vec3<T> D0 = m_dir;
vec3<T> D1 = a_line.m_dir;
vec3<T> D0N = D0;
VEC3 P0 = m_pos;
VEC3 P1 = a_line.m_pos;
VEC3 D0 = m_dir;
VEC3 D1 = a_line.m_dir;
VEC3 D0N = D0;
T c[3], d[3];
@@ -116,8 +116,8 @@ public:
return true;
}
bool intersect(const line<T>& a_line,vec3<T>& a_out,const T& a_prec) const {
vec3<T> p,q;
bool intersect(const line<T>& a_line,VEC3& a_out,const T& a_prec) const {
VEC3 p,q;
if(!closest_points(a_line,p,q)) return false;
if((q-p).length()>a_prec) return false;
a_out = p;
@@ -126,8 +126,8 @@ public:
*/
protected:
vec3<T> m_pos;
vec3<T> m_dir; //normalized.
VEC3 m_pos;
VEC3 m_dir; //normalized.
};
}
+25 -105
View File
@@ -5,7 +5,7 @@
#define tools_mat
#ifdef TOOLS_MEM
#include "mem"
#include "../mem"
#endif
#include "MATCOM"
@@ -30,9 +30,11 @@ private:
}
#endif
public:
mat() {
mat(bool a_inc = true) {
#ifdef TOOLS_MEM
mem::increment(s_class().c_str());
if(a_inc) mem::increment(s_class().c_str());
#else
(void)a_inc;
#endif
#ifdef TOOLS_MAT_NEW
m_vec = new T[D*D];
@@ -160,18 +162,18 @@ inline nmat<T> copy(const mat<T,D>& a_from) {
}
template <class MAT>
inline void conjugate(MAT& a_m) {
inline void conjugate(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) {
typedef typename MAT::elem_t T;
T* pos = const_cast<T*>(a_m.data());
unsigned int D2 = a_m.dimension()*a_m.dimension();
for(unsigned int i=0;i<D2;i++,pos++) {
*pos = _conj(*pos); //T = std::complex<>
*pos = a_conj(*pos); //T = std::complex<>
}
}
template <class MAT>
inline void dagger(MAT& a_m) {
conjugate<MAT>(a_m);
inline void dagger(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) {
conjugate<MAT>(a_m,a_conj);
a_m.transpose();
}
@@ -359,37 +361,6 @@ inline void matrix_set(MAT& a_m
vec[1] = a_10;vec[3] = a_11;
}
template <class MAT>
inline void set_epsilon(MAT& a_m) {
matrix_set<MAT>(a_m, 0, 1,
-1, 0);
}
// Pauli matrices :
// P1 P2 P3
// 0 1 0 -i 1 0
// 1 0 i 0 0 -1
template <class MAT>
inline void set_P1(MAT& a_m) {
matrix_set<MAT>(a_m, 0, 1,
1, 0);
}
template <class MAT>
inline void set_P2(MAT& a_m) {
typedef typename MAT::elem_t T;
//T i;set_i(i); //with inlib::symbol
T i(0,1);
T _i = T(-1)*i;
matrix_set<MAT>(a_m, 0, _i,
i, 0);
}
template <class MAT>
inline void set_P3(MAT& a_m) {
matrix_set<MAT>(a_m, 1, 0,
0,-1);
}
////////////////////////////////////////////////
/// specific D=3 ///////////////////////////////
////////////////////////////////////////////////
@@ -407,27 +378,6 @@ inline void matrix_set(MAT& a_m
vec[2] = a_20;vec[5] = a_21;vec[8] = a_22;
}
// Generators of rotation group :
// Rk(i,j) = epsilon(k,i,j) i,j,k=1,2,3
template <class MAT>
inline void set_R1(MAT& a_m) {
matrix_set<MAT>(a_m, 0, 0, 0,
0, 0, 1,
0,-1, 0);
}
template <class MAT>
inline void set_R2(MAT& a_m) {
matrix_set<MAT>(a_m, 0, 0,-1,
0, 0, 0,
1, 0, 0);
}
template <class MAT>
inline void set_R3(MAT& a_m) {
matrix_set<MAT>(a_m, 0, 1, 0,
-1, 0, 0,
0, 0, 0);
}
////////////////////////////////////////////////
/// specific D=4 ///////////////////////////////
////////////////////////////////////////////////
@@ -447,56 +397,26 @@ inline void matrix_set(MAT& a_m
vec[3] = a_30;vec[7] = a_31;vec[11] = a_32;vec[15] = a_33;
}
template <class MAT,class RANDOM>
inline void set_random_antisym(MAT& a_m,RANDOM& a_rd) {
typedef typename MAT::elem_t T;
T v01 = a_rd.shoot();
T v02 = a_rd.shoot();
T v03 = a_rd.shoot();
T v12 = a_rd.shoot();
T v13 = a_rd.shoot();
T v23 = a_rd.shoot();
matrix_set(a_m,
0, v01, v02, v03,
-v01, 0, v12, v13,
-v02,-v12, 0, v23,
-v03,-v13,-v23, 0);
}
////////////////////////////////////////////////
/// specific D=5 ///////////////////////////////
////////////////////////////////////////////////
template <class MAT>
inline void set_eta(MAT& a_m) {
a_m.set_zero();
a_m.set_value(0,0, 1);
a_m.set_value(1,1,-1);
a_m.set_value(2,2,-1);
a_m.set_value(3,3,-1);
}
////////////////////////////////////////////////
/// specific D=6 ///////////////////////////////
////////////////////////////////////////////////
/*
template <class T>
inline void set_matrix(mat<T,6>& a_m
,const T& a_00,const T& a_01,const T& a_02,const T& a_03,const T& a_04,const T& a_05 //1 row
,const T& a_10,const T& a_11,const T& a_12,const T& a_13,const T& a_14,const T& a_15 //2 row
,const T& a_20,const T& a_21,const T& a_22,const T& a_23,const T& a_24,const T& a_25 //3 row
,const T& a_30,const T& a_31,const T& a_32,const T& a_33,const T& a_34,const T& a_35 //4 row
,const T& a_40,const T& a_41,const T& a_42,const T& a_43,const T& a_44,const T& a_45 //5 row
,const T& a_50,const T& a_51,const T& a_52,const T& a_53,const T& a_54,const T& a_55 //6 row
inline void matrix_set(MAT& a_m
,const typename MAT::elem_t& a_00,const typename MAT::elem_t& a_01,const typename MAT::elem_t& a_02,const typename MAT::elem_t& a_03,const typename MAT::elem_t& a_04 //1 row
,const typename MAT::elem_t& a_10,const typename MAT::elem_t& a_11,const typename MAT::elem_t& a_12,const typename MAT::elem_t& a_13,const typename MAT::elem_t& a_14 //2 row
,const typename MAT::elem_t& a_20,const typename MAT::elem_t& a_21,const typename MAT::elem_t& a_22,const typename MAT::elem_t& a_23,const typename MAT::elem_t& a_24 //3 row
,const typename MAT::elem_t& a_30,const typename MAT::elem_t& a_31,const typename MAT::elem_t& a_32,const typename MAT::elem_t& a_33,const typename MAT::elem_t& a_34 //4 row
,const typename MAT::elem_t& a_40,const typename MAT::elem_t& a_41,const typename MAT::elem_t& a_42,const typename MAT::elem_t& a_43,const typename MAT::elem_t& a_44 //5 row
){
//a_<R><C>
//vec[R + C * 6];
T* vec = const_cast<T*>(a_m.data());
vec[0] = a_00;vec[6] = a_01;vec[12] = a_02;vec[18] = a_03;vec[24] = a_04;vec[30] = a_05;
vec[1] = a_10;vec[7] = a_11;vec[13] = a_12;vec[19] = a_13;vec[25] = a_14;vec[31] = a_15;
vec[2] = a_20;vec[8] = a_21;vec[14] = a_22;vec[20] = a_23;vec[26] = a_24;vec[32] = a_25;
vec[3] = a_30;vec[9] = a_31;vec[15] = a_32;vec[21] = a_33;vec[27] = a_34;vec[33] = a_35;
vec[4] = a_40;vec[10] = a_41;vec[16] = a_42;vec[22] = a_43;vec[28] = a_44;vec[34] = a_45;
vec[5] = a_50;vec[11] = a_51;vec[17] = a_52;vec[23] = a_53;vec[29] = a_54;vec[35] = a_55;
//vec[R + C * 4];
typename MAT::elem_t* vec = const_cast<typename MAT::elem_t*>(a_m.data());
vec[0] = a_00;vec[5] = a_01;vec[10] = a_02;vec[15] = a_03;vec[20] = a_04;
vec[1] = a_10;vec[6] = a_11;vec[11] = a_12;vec[16] = a_13;vec[21] = a_14;
vec[2] = a_20;vec[7] = a_21;vec[12] = a_22;vec[17] = a_23;vec[22] = a_24;
vec[3] = a_30;vec[8] = a_31;vec[13] = a_32;vec[18] = a_33;vec[23] = a_34;
vec[4] = a_40;vec[9] = a_41;vec[14] = a_42;vec[19] = a_43;vec[24] = a_44;
}
*/
}
+47 -13
View File
@@ -6,7 +6,7 @@
#include "mat"
#include <cmath>
//#include <cmath>
namespace tools {
@@ -15,7 +15,7 @@ class mat4 : public mat<T,4> {
typedef mat<T,4> parent;
typedef mat<T,4> pr;
public:
mat4():parent() {}
mat4(bool a_inc = true):parent(a_inc) {}
mat4(const mat<T,4>& a_from):parent(a_from){}
virtual ~mat4() {}
public:
@@ -62,8 +62,8 @@ public:
void set_translate(const T& a_x,const T& a_y,const T& a_z) {
_set_translate(a_x,a_y,a_z,pr::m_vec);
}
void set_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle) {
_set_rotate(a_x,a_y,a_z,a_angle,pr::m_vec);
void set_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
_set_rotate(a_x,a_y,a_z,a_angle,pr::m_vec,a_sin,a_cos);
}
void set_ortho(const T& a_l,const T& a_r, //left,right
const T& a_b,const T& a_t, //bottom,top
@@ -155,6 +155,13 @@ public:
a_y = pr::m_vec[13];
a_z = pr::m_vec[14];
}
//void set_translate_only(const T& a_x,const T& a_y,const T& a_z) {
// pr::m_vec[12] = a_x;
// pr::m_vec[13] = a_y;
// pr::m_vec[14] = a_z;
//}
public:
void mul_4(T& a_x,T& a_y,T& a_z,T& a_p) const {
// a_[x,y,z,p] = this * a_[x,y,z,p]
@@ -211,6 +218,14 @@ public:
a_z = z;
}
void mul_trans_3(T& a_x,T& a_y,T& a_z) const {
// used in sg::healpix.
// a_[x,y,z] = trans_part(this) * a_[x,y,z]
a_x += pr::m_vec[12];
a_y += pr::m_vec[13];
a_z += pr::m_vec[14];
}
template <class VEC>
void mul_dir_3(VEC& a_dir) const {
mul_dir_3(a_dir[0],a_dir[1],a_dir[2]);
@@ -261,16 +276,15 @@ public:
pr::m_vec[15] = pr::m_vec[3]*a_x+pr::m_vec[7]*a_y+pr::m_vec[11]*a_z+pr::m_vec[15];
}
void mul_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle) {
void mul_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
T rot[16];
_set_rotate(a_x,a_y,a_z,a_angle,rot);
_set_rotate(a_x,a_y,a_z,a_angle,rot,a_sin,a_cos);
parent::_mul_mtx(rot);
}
void left_mul_rotate(const T& a_x,const T& a_y,const T& a_z,
const T& a_angle) {
void left_mul_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
T _m[16];
_set_rotate(a_x,a_y,a_z,a_angle,_m);
_set_rotate(a_x,a_y,a_z,a_angle,_m,a_sin,a_cos);
parent::_left_mul_mtx(_m);
}
@@ -340,11 +354,11 @@ protected:
v[2] = 0;v[6] = 0;v[10] = a_3;v[14] = 0;
v[3] = 0;v[7] = 0;v[11] = 0;v[15] = T(1);
}
static void _set_rotate(const T& a_x,const T& a_y,const T& a_z,
const T& a_angle,T v[]) {
static void _set_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T v[],T(*a_sin)(T),T(*a_cos)(T)) {
//WARNING : (a_x,a_y,a_z) must be a normalized vector.
T co = (T)::cos(a_angle);
T si = (T)::sin(a_angle);
T si = a_sin(a_angle);
T co = a_cos(a_angle);
T x = a_x;
T y = a_y;
T z = a_z;
@@ -447,6 +461,26 @@ public:
private:static void check_instantiation() {mat4<float> dummy;}
};
////////////////////////////////////////////////
/// common matrices : //////////////////////////
////////////////////////////////////////////////
template <class T>
inline const mat4<T>& mat4_zero() {
static const mat4<T> s_v(false); //inc mem count = false
return s_v;
}
/*
template <class T>
inline const mat4<T>& mat4_identity() {
static mat4<T> s_v(false);
static bool s_first = true;
if(s_first) {s_v.set_identity();s_first=false;}
return s_v;
}
*/
//for sf, mf :
template <class T>
inline const T* get_data(const mat4<T>& a_v) {return a_v.data();}
@@ -5,17 +5,19 @@
#define tools_mat4f
#include "mat4"
#include <cmath>
namespace tools {
class mat4f : public mat4<float> {
typedef mat4<float> parent;
public:
mat4f(){}
virtual ~mat4f() {}
public:
mat4f(const mat4f& a_from):mat4<float>(a_from){}
mat4f(const mat4f& a_from):parent(a_from){}
mat4f& operator=(const mat4f& a_from){
mat4<float>::operator=(a_from);
parent::operator=(a_from);
return *this;
}
public:
@@ -23,28 +25,38 @@ public:
float a_10,float a_11,float a_12,float a_13, //second row
float a_20,float a_21,float a_22,float a_23, //third row
float a_30,float a_31,float a_32,float a_33) //fourth row
:mat4<float>(a_00,a_01,a_02,a_03,
a_10,a_11,a_12,a_13,
a_20,a_21,a_22,a_23,
a_30,a_31,a_32,a_33)
:parent(a_00,a_01,a_02,a_03,
a_10,a_11,a_12,a_13,
a_20,a_21,a_22,a_23,
a_30,a_31,a_32,a_33)
{}
mat4f(const mat4<float>& a_from):mat4<float>(a_from){}
mat4f& operator=(const mat4<float>& a_from){
mat4<float>::operator=(a_from);
mat4f(const parent& a_from):parent(a_from){}
mat4f& operator=(const parent& a_from){
parent::operator=(a_from);
return *this;
}
public:
void set_rotate(const float& a_x,const float& a_y,const float& a_z,const float& a_angle) {
parent::set_rotate(a_x,a_y,a_z,a_angle,::sinf,::cosf);
}
void mul_rotate(const float& a_x,const float& a_y,const float& a_z,const float& a_angle) {
parent::mul_rotate(a_x,a_y,a_z,a_angle,::sinf,::cosf);
}
void left_mul_rotate(const float& a_x,const float& a_y,const float& a_z,const float& a_angle) {
parent::left_mul_rotate(a_x,a_y,a_z,a_angle,::sinf,::cosf);
}
public: //backward compatibility
void mul_2f(float& a_x,float& a_y) const {
mat4<float>::mul_2(a_x,a_y);
}
void mul_3f(float& a_x,float& a_y,float& a_z) const {
mat4<float>::mul_3(a_x,a_y,a_z);
}
void mul_dir_3f(float& a_x,float& a_y,float& a_z) const {
mat4<float>::mul_dir_3(a_x,a_y,a_z);
}
void mul_4f(float& a_x,float& a_y,float& a_z,float& a_w) const {
mat4<float>::mul_4(a_x,a_y,a_z,a_w);
void mul_2f(float& a_x,float& a_y) const {parent::mul_2(a_x,a_y);}
void mul_3f(float& a_x,float& a_y,float& a_z) const {parent::mul_3(a_x,a_y,a_z);}
void mul_dir_3f(float& a_x,float& a_y,float& a_z) const {parent::mul_dir_3(a_x,a_y,a_z);}
void mul_trans_3f(float& a_x,float& a_y,float& a_z) const {parent::mul_trans_3(a_x,a_y,a_z);}
void mul_4f(float& a_x,float& a_y,float& a_z,float& a_w) const {parent::mul_4(a_x,a_y,a_z,a_w);}
void mul_dir_3d(double& a_x,double& a_y,double& a_z) const { //used in sg::healpix
float x = float(a_x);
float y = float(a_y);
float z = float(a_z);
parent::mul_dir_3(x,y,z);
a_x = x;a_y = y;a_z = z;
}
public: //operators
};
@@ -8,21 +8,23 @@
namespace tools {
template <class T>
template <class VEC3>
class plane {
protected:
typedef typename VEC3::elem_t T;
public:
plane(){}
plane(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2) {
plane(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2) {
// Construct a plane given 3 points.
// Orientation is computed by taking (p1 - p0) x (p2 - p0) and
// pointing the normal in that direction.
vec3<T> P = a_p1;
VEC3 P = a_p1;
P.subtract(a_p0);
vec3<T> P2 = a_p2;
VEC3 P2 = a_p2;
P2.subtract(a_p0);
m_normal = P.cross(P2);
P.cross(P2,m_normal);
if(!m_normal.normalize()) {} //throw
m_distance =
m_normal.v0() * a_p0.v0() +
@@ -30,11 +32,11 @@ public:
m_normal.v2() * a_p0.v2();
}
plane(const vec3<T>& a_normal,const T& a_distance){
plane(const VEC3& a_normal,const T& a_distance){
set(a_normal,a_distance);
}
plane(const vec3<T>& a_normal,const vec3<T>& a_point){
plane(const VEC3& a_normal,const VEC3& a_point){
set(a_normal,a_point);
}
@@ -58,11 +60,11 @@ public:
m_distance += a_distance;
}
bool intersect(const line<T>& a_line,vec3<T>& a_intersection) const {
bool intersect(const line<VEC3>& a_line,VEC3& a_intersection) const {
// Intersect line and plane, returning true if there is an intersection
// false if line is parallel to plane
const vec3<T>& pos = a_line.position();
const vec3<T>& dir = a_line.direction();
const VEC3& pos = a_line.position();
const VEC3& dir = a_line.direction();
T d = m_normal.dot(dir);
if(d==T()) return false;
T t = (m_distance - m_normal.dot(pos))/d;
@@ -73,33 +75,33 @@ public:
return true;
}
bool is_in_half_space(const vec3<T>& a_point) const {
bool is_in_half_space(const VEC3& a_point) const {
// Returns true if the given point is within the half-space
// defined by the plane
//vec pos = m_normal * m_distance;
vec3<T> pos = m_normal;
VEC3 pos = m_normal;
pos.multiply(-m_distance);
pos.add(a_point);
return (m_normal.dot(pos) >= T() ? true : false);
}
const vec3<T>& normal() const {return m_normal;}
const VEC3& normal() const {return m_normal;}
T distance_from_origin() const {return m_distance;}
T distance(const vec3<T>& a_point) const {
T distance(const VEC3& a_point) const {
// Return the distance from point to plane. Positive distance means
// the point is in the plane's half space.
return a_point.dot(m_normal) - m_distance;
}
void set(const vec3<T>& a_normal,const T& a_distance){
void set(const VEC3& a_normal,const T& a_distance){
m_normal = a_normal;
if(!m_normal.normalize()) {} //throw
m_distance = a_distance;
}
void set(const vec3<T>& a_normal,const vec3<T>& a_point){
void set(const VEC3& a_normal,const VEC3& a_point){
// Construct a plane given normal and a point to pass through
// Orientation is given by the normal vector n.
m_normal = a_normal;
@@ -111,12 +113,12 @@ public:
}
public: //iv2sg
const vec3<T>& getNormal() const {return m_normal;}
const VEC3& getNormal() const {return m_normal;}
protected:
// equation of the plane is :
// norm[0]*x+norm[1]*y+norm[2]*z = dist
vec3<T> m_normal; //normalized.
VEC3 m_normal; //normalized.
T m_distance;
};
+35 -35
View File
@@ -6,23 +6,21 @@
// rotation done with quaternion.
#include "vec4"
#include "vec3"
#include "mat4"
namespace tools {
template <class T>
template <class VEC3,class VEC4>
class qrot {
protected:
//typedef typename VEC3::elem_t T3;
typedef typename VEC4::elem_t T; //we assume = T3
public:
qrot()
:m_quat(0,0,0,1) //zero rotation around the positive Z axis.
{}
qrot(const vec3<T>& a_axis,T a_radians){
if(!set_value(a_axis,a_radians)) {} //FIXME : throw
qrot(const VEC3& a_axis,T a_radians,T(*a_sin)(T),T(*a_cos)(T)){
if(!set_value(a_axis,a_radians,a_sin,a_cos)) {} //FIXME : throw
}
qrot(const vec3<T>& a_from,const vec3<T>& a_to){set_value(a_from,a_to);}
qrot(const VEC3& a_from,const VEC3& a_to,T(*a_sqrt)(T),T(*a_fabs)(T)){set_value(a_from,a_to,a_sqrt,a_fabs);}
virtual ~qrot(){}
public:
qrot(const qrot& a_from)
@@ -108,14 +106,14 @@ public:
}
bool set_value(const vec3<T>& a_axis,T a_radians) {
bool set_value(const VEC3& a_axis,T a_radians,T(*a_sin)(T),T(*a_cos)(T)) {
// Reset rotation with the given axis-of-rotation and rotation angle.
// Make sure axis is not the null vector when calling this method.
// From <http://www.automation.hut.fi/~jaro/thesis/hyper/node9.html>.
if(a_axis.length()==T()) return false;
m_quat.v3(::cos(a_radians/2));
T sineval = ::sin(a_radians/2);
vec3<T> a = a_axis;
m_quat.v3(a_cos(a_radians/2));
T sineval = a_sin(a_radians/2);
VEC3 a = a_axis;
a.normalize();
m_quat.v0(a.v0() * sineval);
m_quat.v1(a.v1() * sineval);
@@ -123,15 +121,15 @@ public:
return true;
}
bool set_value(const vec3<T>& a_from,const vec3<T>& a_to) {
bool set_value(const VEC3& a_from,const VEC3& a_to,T(*a_sqrt)(T),T(*a_fabs)(T)) {
// code taken from coin3d/SbRotation.
vec3<T> from(a_from);
VEC3 from(a_from);
if(from.normalize()==T()) return false;
vec3<T> to(a_to);
VEC3 to(a_to);
if(to.normalize()==T()) return false;
T dot = from.dot(to);
vec3<T> crossvec = from.cross(to);
VEC3 crossvec;from.cross(to,crossvec);
T crosslen = crossvec.normalize();
if(crosslen == T()) { // Parallel vectors
@@ -142,10 +140,10 @@ public:
// Ok, so they are parallel and pointing in the opposite direction
// of each other.
// Try crossing with x axis.
vec3<T> t = from.cross(vec3<T>(1,0,0));
VEC3 t;from.cross(VEC3(1,0,0),t);
// If not ok, cross with y axis.
if(t.normalize() == T()) {
t = from.cross(vec3<T>(0,1,0));
from.cross(VEC3(0,1,0),t);
t.normalize();
}
m_quat.set_value(t[0],t[1],t[2],0);
@@ -153,17 +151,17 @@ public:
} else { // Vectors are not parallel
// The fabs() wrapping is to avoid problems when `dot' "overflows"
// a tiny wee bit, which can lead to sqrt() returning NaN.
crossvec *= (T)::sqrt(half() * ::fabs(one() - dot));
crossvec *= (T)a_sqrt(half() * a_fabs(one() - dot));
// The fabs() wrapping is to avoid problems when `dot' "underflows"
// a tiny wee bit, which can lead to sqrt() returning NaN.
m_quat.set_value(crossvec[0], crossvec[1], crossvec[2],(T)::sqrt(half()*::fabs(one()+dot)));
m_quat.set_value(crossvec[0], crossvec[1], crossvec[2],(T)a_sqrt(half()*a_fabs(one()+dot)));
}
return true;
}
bool value(vec3<T>& a_axis,T& a_radians) const {
bool value(VEC3& a_axis,T& a_radians,T(*a_sin)(T),T(*a_acos)(T)) const { //WARNING a_acos and NOT a_cos
//WARNING : can fail.
if( (m_quat.v3()<minus_one()) || (m_quat.v3()> one()) ){ ////???
a_axis.set_value(0,0,1);
@@ -171,8 +169,8 @@ public:
return false;
}
a_radians = ::acos(m_quat.v3()) * 2;
T sineval = ::sin(a_radians/2);
a_radians = a_acos(m_quat.v3()) * 2;
T sineval = a_sin(a_radians/2);
if(sineval==T()) { //???
a_axis.set_value(0,0,1);
@@ -185,14 +183,15 @@ public:
return true;
}
void set_value(const mat4<T>& a_m) {
template <class MAT4>
void set_value(const MAT4& a_m,T(*a_sqrt)(T)) {
//WARNING : not tested.
//Set the rotation from the components of the given matrix.
T scalerow = a_m.v00() + a_m.v11() + a_m.v22();
if (scalerow > T()) {
T _s = ::sqrt(scalerow + a_m.v33());
T _s = a_sqrt(scalerow + a_m.v33());
m_quat.v3(_s * half());
_s = half() / _s;
@@ -207,7 +206,7 @@ public:
unsigned int j = (i+1)%3;
unsigned int k = (j+1)%3;
T _s = ::sqrt((a_m.value(i,i) - (a_m.value(j,j) + a_m.value(k,k))) + a_m.v33());
T _s = a_sqrt((a_m.value(i,i) - (a_m.value(j,j) + a_m.value(k,k))) + a_m.v33());
m_quat.set_value(i,_s * half());
_s = half() / _s;
@@ -218,11 +217,12 @@ public:
}
if (a_m.v33()!=one()) {
m_quat.multiply(one()/::sqrt(a_m.v33()));
m_quat.multiply(one()/a_sqrt(a_m.v33()));
}
}
void value(mat4<T>& a_m) const {
template <class MAT4>
void value(MAT4& a_m) const {
//Return this rotation in the form of a matrix.
const T x = m_quat.v0();
const T y = m_quat.v1();
@@ -255,7 +255,7 @@ public:
a_m.v33(w*w + x*x + y*y + z*z);
}
void mul_vec(const vec3<T>& a_in,vec3<T>& a_out) const {
void mul_vec(const VEC3& a_in,VEC3& a_out) const {
const T x = m_quat.v0();
const T y = m_quat.v1();
const T z = m_quat.v2();
@@ -277,7 +277,7 @@ public:
a_out.set_value(v0,v1,v2);
}
void mul_vec(vec3<T>& a_v) const {
void mul_vec(VEC3& a_v) const {
const T x = m_quat.v0();
const T y = m_quat.v1();
const T z = m_quat.v2();
@@ -324,8 +324,8 @@ public:
}
public: //for io::streamer
const vec4<T>& quat() const {return m_quat;}
vec4<T>& quat() {return m_quat;}
const VEC4& quat() const {return m_quat;}
VEC4& quat() {return m_quat;}
protected:
static T one() {return T(1);}
@@ -333,7 +333,7 @@ protected:
static T half() {return T(0.5);}
protected:
vec4<T> m_quat;
VEC4 m_quat;
public:
//NOTE : don't handle a static object because of mem balance.
@@ -342,7 +342,7 @@ public:
// return s_v;
//}
private:static void check_instantiation() {qrot<float> v;}
//private:static void check_instantiation() {qrot<float> v;}
};
}
+20 -21
View File
@@ -8,35 +8,29 @@
#include "qrot"
#include "vec3f"
#include "vec4f"
#include "mat4f"
namespace tools {
class rotf : public qrot<float> {
rotf(float a_q0,float a_q1,float a_q2,float a_q3)
:qrot<float>(a_q0,a_q1,a_q2,a_q3)
{}
class rotf : public qrot<vec3f,vec4f> {
typedef qrot<vec3f,vec4f> parent;
private:
rotf(float a_q0,float a_q1,float a_q2,float a_q3):parent(a_q0,a_q1,a_q2,a_q3) {}
public:
rotf()
:qrot<float>() //zero rotation around the positive Z axis.
{}
rotf(const vec3f& a_axis,float a_radians)
:qrot<float>(a_axis,a_radians)
{}
rotf(const vec3f& a_from,const vec3f& a_to)
:qrot<float>(a_from,a_to)
{}
rotf():parent() {} //zero rotation around the positive Z axis.
rotf(const vec3f& a_axis,float a_radians):parent(a_axis,a_radians,::sinf,::cosf) {}
rotf(const vec3f& a_from,const vec3f& a_to):parent(a_from,a_to,::sqrtf,::fabsf) {}
virtual ~rotf(){}
public:
rotf(const rotf& a_from)
:qrot<float>(a_from)
{}
rotf(const rotf& a_from):parent(a_from) {}
rotf& operator=(const rotf& a_from){
qrot<float>::operator=(a_from);
parent::operator=(a_from);
return *this;
}
public:
rotf& operator*=(const rotf& a_q) {
qrot<float>::operator*=(a_q);
parent::operator*=(a_q);
return *this;
}
rotf operator*(const rotf& a_r) const {
@@ -46,11 +40,16 @@ public:
}
public:
bool set_value(const vec3f& a_from,const vec3f& a_to){
return qrot<float>::set_value(a_from,a_to);
return parent::set_value(a_from,a_to,::sqrtf,::fabsf);
}
bool set_value(const vec3f& a_from,float a_a){
return qrot<float>::set_value(a_from,a_a);
return parent::set_value(a_from,a_a,::sinf,::cosf);
}
bool value(vec3f& a_from,float a_a) const {
return parent::value(a_from,a_a,::sinf,::acosf); //WARNING acos and not cos
}
void set_value(const mat4f& a_m) {parent::set_value(a_m,::sqrtf);}
void value(mat4f& a_m) const {parent::value(a_m);}
//NOTE : don't handle a static object because of mem balance.
//static const rotf& identity() {
@@ -67,7 +66,7 @@ namespace tools {
inline bool tos(const rotf& a_v,std::string& a_s) {
vec3f axis;
float angle;
float angle = 0;
if(!a_v.value(axis,angle)) {a_s.clear();return false;}
std::ostringstream strm;
strm << axis[0] << " "
+15 -12
View File
@@ -4,10 +4,10 @@
#ifndef tools_vec2
#define tools_vec2
#include <cmath> //sqrt
#include <cstddef> //size_t
#ifdef TOOLS_MEM
#include "mem"
#include "../mem"
#endif
namespace tools {
@@ -21,6 +21,7 @@ class vec2 {
}
#endif
public:
typedef T elem_t;
unsigned int dimension() const {return 2;}
public:
vec2(){
@@ -63,14 +64,16 @@ public:
return *this;
}
public:
T v0() const { return m_data[0];}
T v1() const { return m_data[1];}
const T& v0() const { return m_data[0];}
const T& v1() const { return m_data[1];}
void v0(const T& a_value) { m_data[0] = a_value;}
void v1(const T& a_value) { m_data[1] = a_value;}
T x() const {return m_data[0];}
T y() const {return m_data[1];}
const T& x() const {return m_data[0];}
const T& y() const {return m_data[1];}
T& x() {return m_data[0];}
T& y() {return m_data[1];}
void set_value(const T& a0,const T& a1) {
m_data[0] = a0;
@@ -91,12 +94,12 @@ public:
// return true;
//}
T length() const {
return (T)::sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]);
T length(T(*a_sqrt)(T)) const {
return a_sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]);
}
T normalize() {
T norme = length();
T normalize(T(*a_sqrt)(T)) {
T norme = length(a_sqrt);
if(norme==T()) return T();
divide(norme);
return norme;
@@ -145,11 +148,11 @@ public:
}
public: //operators
T& operator[](unsigned int a_index) {
T& operator[](size_t a_index) {
//WARNING : no check on a_index.
return m_data[a_index];
}
const T& operator[](unsigned int a_index) const {
const T& operator[](size_t a_index) const {
//WARNING : no check on a_index.
return m_data[a_index];
}
@@ -6,6 +6,7 @@
#include "vec2"
#include "../S_STRING"
#include <cmath>
namespace tools {
@@ -53,6 +54,22 @@ public: //operators
vec2f operator-() const {
return vec2f(-m_data[0],-m_data[1]);
}
public:
#define TOOLS_VEC2F_MORE_PREC
#ifdef TOOLS_VEC2F_MORE_PREC
float length() const {
return float(::sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]));
}
float normalize() {
float norme = length();
if(!norme) return 0;
divide(norme);
return norme;
}
#else
float length() const {return parent::length(::sqrtf);}
float normalize() {return parent::normalize(::sqrtf);}
#endif
public: //iv2sg
bool equals(const vec2f& a_v,const float a_epsil) const {
//if(a_epsil<0.0f))
+102 -41
View File
@@ -4,10 +4,10 @@
#ifndef tools_vec3
#define tools_vec3
#include <cmath> //sqrt
#include <cstddef> //size_t
#ifdef TOOLS_MEM
#include "mem"
#include "../mem"
#endif
namespace tools {
@@ -71,17 +71,21 @@ public:
return *this;
}
public:
T v0() const { return m_data[0];}
T v1() const { return m_data[1];}
T v2() const { return m_data[2];}
const T& v0() const { return m_data[0];}
const T& v1() const { return m_data[1];}
const T& v2() const { return m_data[2];}
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;}
T x() const {return m_data[0];}
T y() const {return m_data[1];}
T z() const {return m_data[2];}
const T& x() const {return m_data[0];}
const T& y() const {return m_data[1];}
const T& z() const {return m_data[2];}
T& x() {return m_data[0];}
T& y() {return m_data[1];}
T& z() {return m_data[2];}
void set_value(const T& a0,const T& a1,const T& a2) {
m_data[0] = a0;
@@ -105,14 +109,12 @@ public:
// return true;
//}
T length() const {
return (T)::sqrt(m_data[0]*m_data[0]
+m_data[1]*m_data[1]
+m_data[2]*m_data[2]);
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]);
}
T normalize() {
T norme = length();
T normalize(T(*a_sqrt)(T)) {
T norme = length(a_sqrt);
if(norme==T()) return T();
divide(norme);
return norme;
@@ -124,10 +126,10 @@ public:
m_data[2] * aV.m_data[2]);
}
vec3<T> cross(const vec3<T>& aV) const {
return vec3<T>(m_data[1] * aV.m_data[2] - m_data[2] * aV.m_data[1],
m_data[2] * aV.m_data[0] - m_data[0] * aV.m_data[2],
m_data[0] * aV.m_data[1] - m_data[1] * aV.m_data[0]);
void cross(const vec3<T>& aV,vec3<T>& a_value) const {
a_value.set_value(m_data[1] * aV.m_data[2] - m_data[2] * aV.m_data[1],
m_data[2] * aV.m_data[0] - m_data[0] * aV.m_data[2],
m_data[0] * aV.m_data[1] - m_data[1] * aV.m_data[0]);
}
bool equal(const vec3& aV) const {
@@ -137,6 +139,23 @@ public:
return true;
}
template <class PREC>
bool equal_prec(const vec3& a_v,PREC a_prec,PREC(*a_fabs)(const T&)) const {
if(&a_v==this) return true;
for(unsigned int index=0;index<3;index++) {
T diff = m_data[index]-a_v.m_data[index];
if(a_fabs(diff)>=a_prec) return false;
}
return true;
}
vec3<T> _cross(const vec3<T>& aV) const {
//not effective.
return vec3<T>(m_data[1] * aV.m_data[2] - m_data[2] * aV.m_data[1],
m_data[2] * aV.m_data[0] - m_data[0] * aV.m_data[2],
m_data[0] * aV.m_data[1] - m_data[1] * aV.m_data[0]);
}
bool divide(const T& a_T) {
if(a_T==T()) return false;
m_data[0] /= a_T;
@@ -175,6 +194,7 @@ public:
m_data[2] -= a2;
}
/*
bool cos_angle(const vec3& a_v,T& a_cos) const {
//WARNING : if ret false, a_cos is not set.
if(length()==T()) return false;
@@ -183,21 +203,22 @@ public:
return true;
}
bool theta_phi(T& a_theta,T& a_phi) const {
*/
bool theta_phi(T& a_theta,T& a_phi,T(*a_sqrt)(T),T(*a_atan2)(T,T)) const {
//WARNING : if ret false, a_theta, a_phi are not set.
if(length()==T()) return false;
a_phi = (T)::atan2(m_data[1],m_data[0]);
T xy = (T)::sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]);
a_theta = (T)::atan2(xy,m_data[2]);
if(length(a_sqrt)==T()) return false;
a_phi = a_atan2(m_data[1],m_data[0]);
T xy = a_sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]);
a_theta = a_atan2(xy,m_data[2]);
return true;
}
public: //operators
T& operator[](unsigned int a_index) {
T& operator[](size_t a_index) {
//WARNING : no check on a_index.
return m_data[a_index];
}
const T& operator[](unsigned int a_index) const {
const T& operator[](size_t a_index) const {
//WARNING : no check on a_index.
return m_data[a_index];
}
@@ -241,6 +262,7 @@ public: //for inlib/sg/sf_vec
typedef unsigned int size_type;
size_type size() const {return 3;}
const T* data() const {return m_data;}
size_type data_size() const {return 3;} //for eqT.
public: //for iv2sg
const T* getValue() const {return m_data;}
void setValue(const T& a0,const T& a1,const T& a2) {
@@ -296,30 +318,69 @@ template <class T>
inline const T* get_data(const vec3<T>& a_v) {return a_v.data();}
template <class T>
inline void normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,vec3<T>& a_nm) {
a_nm = (a_p1-a_p0).cross(a_p2-a_p1);
a_nm.normalize();
inline void normal(const vec3<T>& a_p0,const vec3<T>& a_p1,const vec3<T>& a_p2,vec3<T>& a_nm,
vec3<T>& a_tmp_1,vec3<T>& a_tmp_2,T(*a_sqrt)(T)) {
// Used to optimize sg::bin().
//(a_p1-a_p0).cross(a_p2-a_p1,a_nm);
a_tmp_1 = a_p1;
a_tmp_1.subtract(a_p0);
a_tmp_2 = a_p2;
a_tmp_2.subtract(a_p1);
a_tmp_1.cross(a_tmp_2,a_nm);
a_nm.normalize(a_sqrt);
}
template <class T>
inline vec3<T> direction(const vec3<T>& a_p0,
const vec3<T>& a_p1,
const vec3<T>& a_p2) {
/*
template <class VEC3>
inline void normal(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,VEC3& a_nm) {
VEC3 tmp1,tmp2;
normal(a_p0,a_p1,a_p2,a_nm,tmp1,tmp2);
}
*/
template <class VEC3>
inline void direction(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,VEC3& a_value) {
// Orientation is computed by taking (p1 - p0) x (p2 - p0)
vec3<T> P = a_p1;
VEC3 P = a_p1;
P.subtract(a_p0);
vec3<T> P2 = a_p2;
VEC3 P2 = a_p2;
P2.subtract(a_p0);
return P.cross(P2);
P.cross(P2,a_value);
}
template <class VEC3>
inline void area(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,typename VEC3::elem_t& a_value,
VEC3& a_tmp_1,VEC3& a_tmp_2,VEC3& a_tmp_3) {
// area of the triangle (a_p0,a_p1,a_p2)
typedef typename VEC3::elem_t T;
a_tmp_1 = a_p1;
a_tmp_1.subtract(a_p0);
a_tmp_2 = a_p2;
a_tmp_2.subtract(a_p1);
a_tmp_1.cross(a_tmp_2,a_tmp_3);
a_value = a_tmp_3.length()/T(2);
}
template <class VEC3>
inline void area(const VEC3& a_p0,const VEC3& a_p1,const VEC3& a_p2,typename VEC3::elem_t& a_value) {
VEC3 tmp1,tmp2,tmp3;
area(a_p0,a_p1,a_p2,a_value,tmp1,tmp2,tmp3);
}
template <class T>
inline vec3<T> direction(const T& a_0_x,const T& a_0_y,const T& a_0_z,
const T& a_1_x,const T& a_1_y,const T& a_1_z,
const T& a_2_x,const T& a_2_y,const T& a_2_z) {
return direction(vec3<T>(a_0_x,a_0_y,a_0_z),
vec3<T>(a_1_x,a_1_y,a_1_z),
vec3<T>(a_2_x,a_2_y,a_2_z));
inline void direction(const T& a_0_x,const T& a_0_y,const T& a_0_z,
const T& a_1_x,const T& a_1_y,const T& a_1_z,
const T& a_2_x,const T& a_2_y,const T& a_2_z,vec3<T>& a_value) {
direction(vec3<T>(a_0_x,a_0_y,a_0_z),
vec3<T>(a_1_x,a_1_y,a_1_z),
vec3<T>(a_2_x,a_2_y,a_2_z),a_value);
}
}
@@ -6,25 +6,27 @@
#include "vec3"
#include "../S_STRING"
#include <cmath>
namespace tools {
class vec3d : public vec3<double> {
typedef vec3<double> parent;
public:
TOOLS_SCLASS(tools::vec3d) //for stype()
public:
vec3d():vec3<double>(){}
vec3d(const double a_vec[3]):vec3<double>(a_vec){}
vec3d(double a0,double a1,double a2):vec3<double>(a0,a1,a2){}
vec3d():parent(){}
vec3d(const double a_vec[3]):parent(a_vec){}
vec3d(double a0,double a1,double a2):parent(a0,a1,a2){}
virtual ~vec3d() {}
public:
vec3d(const vec3d& a_from):vec3<double>(a_from){}
vec3d(const vec3d& a_from):parent(a_from){}
vec3d& operator=(const vec3d& a_from){
vec3<double>::operator=(a_from);
parent::operator=(a_from);
return *this;
}
vec3d(const vec3<double>& a_from):vec3<double>(a_from){}
vec3d(const parent& a_from):parent(a_from){}
public: //operators
vec3d operator*(double a_v) const {
@@ -63,6 +65,9 @@ public: //operators
vec3d operator-() const {
return vec3d(-m_data[0],-m_data[1],-m_data[2]);
}
public:
double length() const {return parent::length(::sqrt);}
double normalize() {return parent::normalize(::sqrt);}
private:static void check_instantiation() {vec3d v(0,0,0);v.set_value(1,1,1);}
};
@@ -6,25 +6,27 @@
#include "vec3"
#include "../S_STRING"
#include <cmath> //sqrt
namespace tools {
class vec3f : public vec3<float> {
typedef vec3<float> parent;
public:
TOOLS_SCLASS(tools::vec3f) //for stype()
public:
vec3f():vec3<float>(){}
vec3f(const float a_vec[3]):vec3<float>(a_vec){}
vec3f(float a0,float a1,float a2):vec3<float>(a0,a1,a2){}
vec3f():parent(){}
vec3f(const float a_vec[3]):parent(a_vec){}
vec3f(float a0,float a1,float a2):parent(a0,a1,a2){}
virtual ~vec3f() {}
public:
vec3f(const vec3f& a_from):vec3<float>(a_from){}
vec3f(const vec3f& a_from):parent(a_from){}
vec3f& operator=(const vec3f& a_from){
vec3<float>::operator=(a_from);
parent::operator=(a_from);
return *this;
}
vec3f(const vec3<float>& a_from):vec3<float>(a_from){}
vec3f(const parent& a_from):parent(a_from){}
public: //operators
vec3f operator*(float a_v) const {
@@ -63,7 +65,26 @@ public: //operators
vec3f operator-() const {
return vec3f(-m_data[0],-m_data[1],-m_data[2]);
}
public:
#define TOOLS_VEC3F_MORE_PREC
#ifdef TOOLS_VEC3F_MORE_PREC
float length() const {
return float(::sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]));
}
float normalize() {
float norme = length();
if(!norme) return 0;
divide(norme);
return norme;
}
#else
float length() const {return parent::length(::sqrtf);}
float normalize() {return parent::normalize(::sqrtf);}
#endif
bool theta_phi(float& a_theta,float& a_phi) const {
return parent::theta_phi(a_theta,a_phi,::sqrtf,::atan2f);
}
public: //iv2sg
bool equals(const vec3f& a_v,const float a_epsil) const {
//if(a_epsil<0.0f))
@@ -87,6 +108,30 @@ inline vec3f operator*(float a_f,const vec3f& a_v) {
return res;
}
#define TOOLS_VEC3F_MORE_PREC
#ifdef TOOLS_VEC3F_MORE_PREC
inline void normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
vec3f& a_tmp_1,vec3f& a_tmp_2) {
// Used to optimize sg::bin().
//(a_p1-a_p0).cross(a_p2-a_p1,a_nm);
a_tmp_1 = a_p1;
a_tmp_1.subtract(a_p0);
a_tmp_2 = a_p2;
a_tmp_2.subtract(a_p1);
a_tmp_1.cross(a_tmp_2,a_nm);
a_nm.normalize();
}
#else
inline void normal(const vec3f& a_p0,const vec3f& a_p1,const vec3f& a_p2,vec3f& a_nm,
vec3f& a_tmp_1,vec3f& a_tmp_2) {
normal<float>(a_p0,a_p1,a_p2,a_nm,a_tmp_1,a_tmp_2,::sqrtf);
}
#endif
}
#include <vector>
+14 -15
View File
@@ -4,10 +4,10 @@
#ifndef tools_vec4
#define tools_vec4
#include <cmath> //sqrt
#include <cstddef> //size_t
#ifdef TOOLS_MEM
#include "mem"
#include "../mem"
#endif
namespace tools {
@@ -15,6 +15,7 @@ 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;
@@ -24,6 +25,7 @@ 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(){
@@ -78,10 +80,10 @@ public:
return *this;
}
public:
T v0() const { return m_data[0];}
T v1() const { return m_data[1];}
T v2() const { return m_data[2];}
T v3() const { return m_data[3];}
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;}
@@ -117,15 +119,12 @@ public:
return true;
}
T length() const {
return (T)::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 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 norme = length();
T normalize(T(*a_sqrt)(T)) {
T norme = length(a_sqrt);
if(norme==T()) return T();
divide(norme);
return norme;
@@ -219,11 +218,11 @@ public:
}
public: //operators
T& operator[](unsigned int a_index) {
T& operator[](size_t a_index) {
//WARNING : no check on a_index.
return m_data[a_index];
}
const T& operator[](unsigned int a_index) const {
const T& operator[](size_t a_index) const {
//WARNING : no check on a_index.
return m_data[a_index];
}
@@ -6,22 +6,24 @@
#include "vec4"
#include "../S_STRING"
#include <cmath>
namespace tools {
class vec4f : public vec4<float> {
typedef vec4<float> parent;
public:
TOOLS_SCLASS(tools::vec4f) //for stype()
public:
vec4f():vec4<float>() {}
vec4f(const float a_vec[4]):vec4<float>(a_vec) {}
vec4f(const float& a0,const float& a1,const float& a2,const float& a3)
:vec4<float>(a0,a1,a2,a3){}
vec4f():parent() {}
vec4f(const float a_vec[4]):parent(a_vec) {}
vec4f(const float& a0,const float& a1,const float& a2,const float& a3,bool a_inc = true)
:parent(a0,a1,a2,a3,a_inc){}
virtual ~vec4f() {}
public:
vec4f(const vec4f& a_from):vec4<float>(a_from){}
vec4f(const vec4f& a_from):parent(a_from){}
vec4f& operator=(const vec4f& a_from){
vec4<float>::operator=(a_from);
parent::operator=(a_from);
return *this;
}
public: //operators
@@ -60,6 +62,22 @@ public: //operators
vec4f operator-() const {
return vec4f(-m_data[0],-m_data[1],-m_data[2],-m_data[3]);
}
public:
#define TOOLS_VEC4F_MORE_PREC
#ifdef TOOLS_VEC4F_MORE_PREC
float length() const {
return float(::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]));
}
float normalize() {
float norme = length();
if(!norme) return 0;
divide(norme);
return norme;
}
#else
float length() const {return parent::length(::sqrtf);}
float normalize() {return parent::normalize(::sqrtf);}
#endif
};
}