updates
parent
f3b4801947
commit
d658df27b3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,214 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
namespace amsmathutil25
|
||||||
|
{
|
||||||
|
|
||||||
|
bool isnan(double d)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(d!=d)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isinf(double d)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = std::isinf(d);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isinfnan(double d)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = ams::isinf(d) || ams::isnan(d);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isnan(float f)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(f!=f)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isinf(float f)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = std::isinf(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isinfnan(float f)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = ams::isinf(f) || ams::isnan(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double arg(double x, double y)
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
double z = ::sqrt(x*x+y*y);
|
||||||
|
|
||||||
|
if(z>1.0E-10)
|
||||||
|
{
|
||||||
|
ret = ::atan2(y,x);
|
||||||
|
if(ret<0.0) ret = ret + 2.0*ams::pi;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float arg(float x, float y)
|
||||||
|
{
|
||||||
|
float ret = 0.0f;
|
||||||
|
float z = ::sqrtf(x*x+y*y);
|
||||||
|
|
||||||
|
if(z>1.0E-10)
|
||||||
|
{
|
||||||
|
ret = ::atan2f(y,x);
|
||||||
|
if(ret<0.0f) ret = ret + ams::pif;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double sgn(double d)
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
ret = (d>0.0) ? 1.0 : ret;
|
||||||
|
ret = (d<0.0) ? -1.0 : ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float sgn(float f)
|
||||||
|
{
|
||||||
|
float ret = 0.0f;
|
||||||
|
ret = (f>0.0f) ? 1.0f : ret;
|
||||||
|
ret = (f<0.0f) ? -1.0f : ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//It has come to my attention that the behavior of Cs
|
||||||
|
//fmod is odd: Negative numbers have negative moduli
|
||||||
|
//I need to fix this with a proper modular function, whose values are in [0,N)
|
||||||
|
double mod(double x, double n)
|
||||||
|
{
|
||||||
|
x = ::fmod(x,n);
|
||||||
|
if(x<0)
|
||||||
|
{
|
||||||
|
x = x + n;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
float mod(float x, float n)
|
||||||
|
{
|
||||||
|
x = ::fmodf(x,n);
|
||||||
|
if(x<0)
|
||||||
|
{
|
||||||
|
x = x + n;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mod(int32_t x, int32_t n)
|
||||||
|
{
|
||||||
|
x = x % n;
|
||||||
|
if(x<0)
|
||||||
|
{
|
||||||
|
x = x + n;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mod(int64_t x, int64_t n)
|
||||||
|
{
|
||||||
|
x = x % n;
|
||||||
|
if(x<0)
|
||||||
|
{
|
||||||
|
x = x + n;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t truediv(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
int32_t z = 0;
|
||||||
|
if(x>=0 && y>0)
|
||||||
|
{
|
||||||
|
z = x/y;
|
||||||
|
}
|
||||||
|
else if(x<0 && y>0)
|
||||||
|
{
|
||||||
|
z = -((-x)/y) - 1;
|
||||||
|
}
|
||||||
|
else if(x>=0 && y<0)
|
||||||
|
{
|
||||||
|
z = -(x/(-y)) - 1;
|
||||||
|
}
|
||||||
|
else if(x<0 && y<0)
|
||||||
|
{
|
||||||
|
z = ((-x)/(-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t truediv(int64_t x, int64_t y)
|
||||||
|
{
|
||||||
|
int64_t z = 0;
|
||||||
|
if(x>=0 && y>0)
|
||||||
|
{
|
||||||
|
z = x/y;
|
||||||
|
}
|
||||||
|
else if(x<0 && y>0)
|
||||||
|
{
|
||||||
|
z = -((-x)/y) - 1;
|
||||||
|
}
|
||||||
|
else if(x>=0 && y<0)
|
||||||
|
{
|
||||||
|
z = -(x/(-y)) - 1;
|
||||||
|
}
|
||||||
|
else if(x<0 && y<0)
|
||||||
|
{
|
||||||
|
z = ((-x)/(-y));
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
double abs(double a)
|
||||||
|
{
|
||||||
|
double ret = ::fabs(a);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float abs(float a)
|
||||||
|
{
|
||||||
|
float ret = ::fabsf(a);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t abs(int32_t a)
|
||||||
|
{
|
||||||
|
int32_t ret = (a<0) ? -a : a;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t abs(int64_t a)
|
||||||
|
{
|
||||||
|
int64_t ret = (a<0) ? -a : a;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,466 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
vec2::vec2()
|
||||||
|
{
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2::vec2(double _x, double _y)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2& vec2::operator=(const vec2 &rhs)
|
||||||
|
{
|
||||||
|
if(this!=&rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec2::operator==(vec2 rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
ret = ret & (rhs.x == x);
|
||||||
|
ret = ret & (rhs.y == y);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2::vec2(const vec2 &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2::operator+(vec2 rhs) const
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2::operator-(vec2 rhs) const
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 operator-(vec2 rhs)
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double& vec2::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& vec2::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec2 vector operations
|
||||||
|
double vec2_dot(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
double ret = v1.x*v2.x + v1.y*v2.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec2_norm(vec2 v)
|
||||||
|
{
|
||||||
|
double ret = ::sqrt(v.x*v.x+v.y*v.y);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2_normalize(vec2 v)
|
||||||
|
{
|
||||||
|
vec2 ret = vec2(0,0);
|
||||||
|
double nrm = vec2_norm(v);
|
||||||
|
if(nrm>0.0)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec2_dist(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
return vec2_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec2_cross(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
double ret = v1.x*v2.y - v1.y*v2.x;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2_proj(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
vec2 v2n = vec2_normalize(v2);
|
||||||
|
ret = v2n*vec2_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vec2_hodgedual(vec2 v)
|
||||||
|
{
|
||||||
|
vec2 ret;
|
||||||
|
ret.x = -v.y;
|
||||||
|
ret.y = v.x;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec2_arg(vec2 v)
|
||||||
|
{
|
||||||
|
double ret;
|
||||||
|
ret = ::atan2(v.y,v.x);
|
||||||
|
if(ret<0.0)
|
||||||
|
{
|
||||||
|
ret = ret + 2.0*ams::pi;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec2 vector operations (old nomenclature)
|
||||||
|
double vdot(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
return vec2_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vnorm(vec2 v)
|
||||||
|
{
|
||||||
|
return vec2_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vnormalize(vec2 v)
|
||||||
|
{
|
||||||
|
return vec2_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vdist(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
return vec2_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vcross(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
return vec2_cross(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 vproj(vec2 v1, vec2 v2)
|
||||||
|
{
|
||||||
|
return vec2_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat2 constructors and operators
|
||||||
|
mat2::mat2()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2::mat2(double _xx, double _yx, double _xy, double _yy)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _xy;
|
||||||
|
data[3] = _yy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2::mat2(const double *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = _data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2::mat2(const mat2 &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = rhs.data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2::mat2(const vec2 _col1, const vec2 _col2)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col2[0];
|
||||||
|
data[3] = _col2[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2& mat2::operator=(const mat2 rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
data[I] = rhs.data[I];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat2::operator==(const mat2 rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
if(data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator+(mat2 rhs) const
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator-(mat2 rhs) const
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator*(mat2 rhs) const
|
||||||
|
{
|
||||||
|
mat2 ret = mat2(0,0,0,0);
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
for(K=0;K<2;K++)
|
||||||
|
ret(I,K) += + (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator/(mat2 rhs) const
|
||||||
|
{
|
||||||
|
mat2 rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mat2::operator*(vec2 rhs) const
|
||||||
|
{
|
||||||
|
vec2 ret = vec2(0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat2::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
if(I==0&&J==0) return data[0];
|
||||||
|
if(I==1&&J==0) return data[1];
|
||||||
|
if(I==0&&J==1) return data[2];
|
||||||
|
if(I==1&&J==1) return data[3];
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat2::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat2::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
if(I==0&&J==0) return data[0];
|
||||||
|
if(I==1&&J==0) return data[1];
|
||||||
|
if(I==0&&J==1) return data[2];
|
||||||
|
if(I==1&&J==1) return data[3];
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat2::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat2::at(int I, int J)
|
||||||
|
{
|
||||||
|
return (*this)(I,J);
|
||||||
|
}
|
||||||
|
const double& mat2::at(int I, int J) const
|
||||||
|
{
|
||||||
|
return (*this)(I,J);
|
||||||
|
}
|
||||||
|
|
||||||
|
double mat2::det()
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
ret = ret + (*this)(0,0)*(*this)(1,1);
|
||||||
|
ret = ret - (*this)(1,0)*(*this)(0,1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::inverse()
|
||||||
|
{
|
||||||
|
mat2 ret = mat2_zeros();
|
||||||
|
double dt = this->det();
|
||||||
|
|
||||||
|
if(dt>=vecmat_det_small || dt<=-vecmat_det_small)
|
||||||
|
{
|
||||||
|
ret(0,0) = (*this)(1,1)/dt;
|
||||||
|
ret(0,1) = -(*this)(0,1)/dt;
|
||||||
|
ret(1,0) = -(*this)(1,0)/dt;
|
||||||
|
ret(1,1) = (*this)(0,0)/dt;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat2::invert()
|
||||||
|
{
|
||||||
|
mat2 q = this->inverse();
|
||||||
|
*this = q;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2::transpose()
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat2::dotranspose()
|
||||||
|
{
|
||||||
|
mat2 t = this->transpose();
|
||||||
|
(*this) = t;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat2 matrix operations
|
||||||
|
mat2 mat2_eye()
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
ret(0,0) = 1.0;
|
||||||
|
ret(1,1) = 1.0;
|
||||||
|
ret(0,1) = 0.0;
|
||||||
|
ret(1,0) = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2_zeros()
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2_ones()
|
||||||
|
{
|
||||||
|
mat2 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2_mult(mat2 a, mat2 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mat2_mult(vec2 a, mat2 b)
|
||||||
|
{
|
||||||
|
vec2 ret = vec2(0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret[J] += a[I]*b(I,J);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mat2_mult(mat2 a, vec2 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mat2_det(mat2 a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2_inverse(mat2 a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2 mat2_transpose(mat2 a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace ams
|
@ -0,0 +1,463 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
vec2f::vec2f()
|
||||||
|
{
|
||||||
|
x = 0.0f;
|
||||||
|
y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f::vec2f(float _x, float _y)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f& vec2f::operator=(const vec2f &rhs)
|
||||||
|
{
|
||||||
|
if(this!=&rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec2f::operator==(vec2f rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
ret = ret & (rhs.x == x);
|
||||||
|
ret = ret & (rhs.y == y);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f::vec2f(const vec2f &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f::operator+(vec2f rhs) const
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f::operator-(vec2f rhs) const
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f operator-(vec2f rhs)
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float& vec2f::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& vec2f::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec2f_dot(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
float ret = v1.x*v2.x + v1.y*v2.y;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec2f_norm(vec2f v)
|
||||||
|
{
|
||||||
|
float ret = ::sqrtf(v.x*v.x+v.y*v.y);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f_normalize(vec2f v)
|
||||||
|
{
|
||||||
|
vec2f ret = vec2f(0.0f,0.0f);
|
||||||
|
float nrm = vec2f_norm(v);
|
||||||
|
if(nrm>0.0f)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec2f_dist(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
return vec2f_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec2f_cross(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
float ret = v1.x*v2.y - v1.y*v2.x;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f_proj(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
vec2f v2n = vec2f_normalize(v2);
|
||||||
|
ret = v2n*vec2f_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vec2f_hodgedual(vec2f v)
|
||||||
|
{
|
||||||
|
vec2f ret;
|
||||||
|
ret.x = -v.y;
|
||||||
|
ret.y = v.x;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec2f_arg(vec2f v)
|
||||||
|
{
|
||||||
|
float ret;
|
||||||
|
ret = ::atan2f(v.y,v.x);
|
||||||
|
if(ret<0.0f)
|
||||||
|
{
|
||||||
|
ret = ret + 2.0f*ams::pif;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec2f vector operations (old nomenclature)
|
||||||
|
float vdot(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
return vec2f_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vnorm(vec2f v)
|
||||||
|
{
|
||||||
|
return vec2f_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vnormalize(vec2f v)
|
||||||
|
{
|
||||||
|
return vec2f_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vdist(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
return vec2f_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vcross(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
return vec2f_cross(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f vproj(vec2f v1, vec2f v2)
|
||||||
|
{
|
||||||
|
return vec2f_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f::mat2f()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f::mat2f(float _xx, float _yx, float _xy, float _yy)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _xy;
|
||||||
|
data[3] = _yy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f::mat2f(const float *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = _data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f::mat2f(const mat2f &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) data[I] = rhs.data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f::mat2f(const vec2f _col1, const vec2f _col2)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col2[0];
|
||||||
|
data[3] = _col2[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f& mat2f::operator=(const mat2f rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
data[I] = rhs.data[I];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat2f::operator==(const mat2f rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
if(data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator+(mat2f rhs) const
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator-(mat2f rhs) const
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator*(mat2f rhs) const
|
||||||
|
{
|
||||||
|
mat2f ret = mat2f(0.0f,0.0f,0.0f,0.0f);
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
for(K=0;K<2;K++)
|
||||||
|
ret(I,K) += + (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator/(mat2f rhs) const
|
||||||
|
{
|
||||||
|
mat2f rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f mat2f::operator*(vec2f rhs) const
|
||||||
|
{
|
||||||
|
vec2f ret = vec2f(0.0f,0.0f);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat2f::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
if(I==0&&J==0) return data[0];
|
||||||
|
if(I==1&&J==0) return data[1];
|
||||||
|
if(I==0&&J==1) return data[2];
|
||||||
|
if(I==1&&J==1) return data[3];
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat2f::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat2f::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
if(I==0&&J==0) return data[0];
|
||||||
|
if(I==1&&J==0) return data[1];
|
||||||
|
if(I==0&&J==1) return data[2];
|
||||||
|
if(I==1&&J==1) return data[3];
|
||||||
|
return data[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat2f::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat2f::at(int I, int J)
|
||||||
|
{
|
||||||
|
return (*this)(I,J);
|
||||||
|
}
|
||||||
|
const float& mat2f::at(int I, int J) const
|
||||||
|
{
|
||||||
|
return (*this)(I,J);
|
||||||
|
}
|
||||||
|
|
||||||
|
float mat2f::det()
|
||||||
|
{
|
||||||
|
float ret = 0.0f;
|
||||||
|
ret = ret + (*this)(0,0)*(*this)(1,1);
|
||||||
|
ret = ret - (*this)(1,0)*(*this)(0,1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::inverse()
|
||||||
|
{
|
||||||
|
mat2f ret = mat2f_zeros();
|
||||||
|
float dt = this->det();
|
||||||
|
|
||||||
|
if(dt>=vecmat_det_small || dt<=-vecmat_det_small)
|
||||||
|
{
|
||||||
|
ret(0,0) = (*this)(1,1)/dt;
|
||||||
|
ret(0,1) = -(*this)(0,1)/dt;
|
||||||
|
ret(1,0) = -(*this)(1,0)/dt;
|
||||||
|
ret(1,1) = (*this)(0,0)/dt;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat2f::invert()
|
||||||
|
{
|
||||||
|
mat2f q = this->inverse();
|
||||||
|
*this = q;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f::transpose()
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat2f::dotranspose()
|
||||||
|
{
|
||||||
|
mat2f t = this->transpose();
|
||||||
|
(*this) = t;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat2f matrix operations
|
||||||
|
mat2f mat2f_eye()
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
ret(0,0) = 1.0f;
|
||||||
|
ret(1,1) = 1.0f;
|
||||||
|
ret(0,1) = 0.0f;
|
||||||
|
ret(1,0) = 0.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f_zeros()
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = 0.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f_ones()
|
||||||
|
{
|
||||||
|
mat2f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<4;I++) ret.data[I] = 1.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f_mult(mat2f a, mat2f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f mat2f_mult(vec2f a, mat2f b)
|
||||||
|
{
|
||||||
|
vec2f ret = vec2f(0.0f,0.0f);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<2;I++)
|
||||||
|
for(J=0;J<2;J++)
|
||||||
|
ret[J] += a[I]*b(I,J);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2f mat2f_mult(mat2f a, vec2f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mat2f_det(mat2f a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f_inverse(mat2f a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2f mat2f_transpose(mat2f a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace ams
|
@ -0,0 +1,506 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
vec3::vec3()
|
||||||
|
{
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
z = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3::vec3(double _x, double _y, double _z)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
z = _z;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3::vec3(const vec3 &rhs)
|
||||||
|
{
|
||||||
|
x = rhs.x;
|
||||||
|
y = rhs.y;
|
||||||
|
z = rhs.z;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3& vec3::operator=(const vec3 &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
this->z = rhs.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec3::operator==(vec3 rhs)
|
||||||
|
{
|
||||||
|
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 arithmetic operators
|
||||||
|
vec3 vec3::operator+(vec3 rhs) const
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
ret.z = this->z + rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3::operator-(vec3 rhs) const
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
ret.z = this->z - rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
ret.z = this->z*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
ret.z = this->z/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 operator-(vec3 rhs)
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
ret.z = -rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 subscript operators
|
||||||
|
double& vec3::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& vec3::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (new nomenclature)
|
||||||
|
double vec3_dot(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
ret += v1.x*v2.x;
|
||||||
|
ret += v1.y*v2.y;
|
||||||
|
ret += v1.z*v2.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec3_norm(vec3 v)
|
||||||
|
{
|
||||||
|
double ret = ::sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3_normalize(vec3 v)
|
||||||
|
{
|
||||||
|
vec3 ret = vec3(0,0,0);
|
||||||
|
double nrm = vec3_norm(v);
|
||||||
|
if(nrm>0.0)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec3_dist(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
return vec3_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3_cross(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
ret[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||||
|
ret[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||||
|
ret[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vec3_proj(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
vec3 ret;
|
||||||
|
vec3 v2n = vec3_normalize(v2);
|
||||||
|
ret = v2n*vec3_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 vec3_hodgedual(vec3 v)
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
|
||||||
|
ret(0,1) = v[2];
|
||||||
|
ret(1,2) = v[0];
|
||||||
|
ret(2,0) = v[1];
|
||||||
|
|
||||||
|
ret(1,0) = -v[2];
|
||||||
|
ret(2,1) = -v[0];
|
||||||
|
ret(0,2) = -v[1];
|
||||||
|
|
||||||
|
ret(0,0) = 0.0;
|
||||||
|
ret(1,1) = 0.0;
|
||||||
|
ret(2,2) = 0.0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (old nomenclature)
|
||||||
|
double vdot(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
return vec3_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vnorm(vec3 v)
|
||||||
|
{
|
||||||
|
return vec3_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vnormalize(vec3 v)
|
||||||
|
{
|
||||||
|
return vec3_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vdist(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
return vec3_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vcross(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
return vec3_cross(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 vproj(vec3 v1, vec3 v2)
|
||||||
|
{
|
||||||
|
return vec3_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3 constructors
|
||||||
|
mat3::mat3()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3::mat3(double _xx, double _yx, double _zx, double _xy, double _yy, double _zy, double _xz, double _yz, double _zz)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _zx;
|
||||||
|
|
||||||
|
data[3] = _xy;
|
||||||
|
data[4] = _yy;
|
||||||
|
data[5] = _zy;
|
||||||
|
|
||||||
|
data[6] = _xz;
|
||||||
|
data[7] = _yz;
|
||||||
|
data[8] = _zz;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3::mat3(const double *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = _data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3::mat3(const mat3 &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = rhs.data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3::mat3(const vec3 _col1, const vec3 _col2, const vec3 _col3)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col1[2];
|
||||||
|
|
||||||
|
data[3] = _col2[0];
|
||||||
|
data[4] = _col2[1];
|
||||||
|
data[5] = _col2[2];
|
||||||
|
|
||||||
|
data[6] = _col3[0];
|
||||||
|
data[7] = _col3[1];
|
||||||
|
data[8] = _col3[2];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3 assignment and comparison operators
|
||||||
|
mat3& mat3::operator=(const mat3 rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = rhs.data[I];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat3::operator==(const mat3 rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
if(this->data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3 arithmetic operators
|
||||||
|
mat3 mat3::operator+(mat3 rhs) const
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::operator-(mat3 rhs) const
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::operator*(mat3 rhs) const
|
||||||
|
{
|
||||||
|
mat3 ret = mat3_zeros();
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
for(K=0;K<3;K++)
|
||||||
|
ret(I,K) += + (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::operator/(mat3 rhs) const
|
||||||
|
{
|
||||||
|
mat3 rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mat3::operator*(vec3 rhs) const
|
||||||
|
{
|
||||||
|
vec3 ret = vec3(0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3 access operators
|
||||||
|
double& mat3::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat3::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat3::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat3::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat3::at(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat3::at(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3 member functions
|
||||||
|
double mat3::det()
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
ret += (*this)(0,0)*(*this)(1,1)*(*this)(2,2);
|
||||||
|
ret += (*this)(0,1)*(*this)(1,2)*(*this)(2,0);
|
||||||
|
ret += (*this)(0,2)*(*this)(1,0)*(*this)(2,1);
|
||||||
|
|
||||||
|
ret -= (*this)(2,0)*(*this)(1,1)*(*this)(0,2);
|
||||||
|
ret -= (*this)(2,1)*(*this)(1,2)*(*this)(0,0);
|
||||||
|
ret -= (*this)(2,2)*(*this)(1,0)*(*this)(0,1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::inverse()
|
||||||
|
{
|
||||||
|
mat3 ret = mat3_zeros();
|
||||||
|
double dt = this->det();
|
||||||
|
if(dt>vecmat_det_small||dt<-vecmat_det_small)
|
||||||
|
{
|
||||||
|
ret(0,0) = (this->at(1,1) * this->at(2,2) - this->at(1,2) * this->at(2,1))/dt;
|
||||||
|
ret(0,1) = -(this->at(1,0) * this->at(2,2) - this->at(1,2) * this->at(2,0))/dt;
|
||||||
|
ret(0,2) = (this->at(1,0) * this->at(2,1) - this->at(1,1) * this->at(2,0))/dt;
|
||||||
|
ret(1,0) = -(this->at(0,1) * this->at(2,2) - this->at(0,2) * this->at(2,1))/dt;
|
||||||
|
ret(1,1) = (this->at(0,0) * this->at(2,2) - this->at(0,2) * this->at(2,0))/dt;
|
||||||
|
ret(1,2) = -(this->at(0,0) * this->at(2,1) - this->at(0,1) * this->at(2,0))/dt;
|
||||||
|
ret(2,0) = (this->at(0,1) * this->at(1,2) - this->at(0,2) * this->at(1,1))/dt;
|
||||||
|
ret(2,1) = -(this->at(0,0) * this->at(1,2) - this->at(0,2) * this->at(1,0))/dt;
|
||||||
|
ret(2,2) = (this->at(0,0) * this->at(1,1) - this->at(0,1) * this->at(1,0))/dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat3::invert()
|
||||||
|
{
|
||||||
|
mat3 m = this->inverse();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3::transpose()
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat3::dotranspose()
|
||||||
|
{
|
||||||
|
mat3 m = this->transpose();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// matrix operations (standalone functions)
|
||||||
|
mat3 mat3_eye()
|
||||||
|
{
|
||||||
|
mat3 ret = mat3_zeros();
|
||||||
|
ret(0,0) = 1.0;
|
||||||
|
ret(1,1) = 1.0;
|
||||||
|
ret(2,2) = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3_zeros()
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
// for speed - the constructor already sets data[I] to 0.0
|
||||||
|
// int I;
|
||||||
|
// for(I=0;I<9;I++) ret.data[I] = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3_ones()
|
||||||
|
{
|
||||||
|
mat3 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3_mult(mat3 a, mat3 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mat3_mult(vec3 a, mat3 b)
|
||||||
|
{
|
||||||
|
vec3 ret = vec3(0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret[J] += a[I] * b(I,J);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mat3_mult(mat3 a, vec3 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mat3_det(mat3 a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3_inverse(mat3 a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 mat3_transpose(mat3 a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,506 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
vec3f::vec3f()
|
||||||
|
{
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
z = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f::vec3f(float _x, float _y, float _z)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
z = _z;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f::vec3f(const vec3f &rhs)
|
||||||
|
{
|
||||||
|
x = rhs.x;
|
||||||
|
y = rhs.y;
|
||||||
|
z = rhs.z;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f& vec3f::operator=(const vec3f &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
this->z = rhs.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec3f::operator==(vec3f rhs)
|
||||||
|
{
|
||||||
|
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3f arithmetic operators
|
||||||
|
vec3f vec3f::operator+(vec3f rhs) const
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
ret.z = this->z + rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f::operator-(vec3f rhs) const
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
ret.z = this->z - rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
ret.z = this->z*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
ret.z = this->z/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f operator-(vec3f rhs)
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
ret.z = -rhs.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3f subscript operators
|
||||||
|
float& vec3f::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& vec3f::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (new nomenclature)
|
||||||
|
float vec3f_dot(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
float ret = 0.0;
|
||||||
|
ret += v1.x*v2.x;
|
||||||
|
ret += v1.y*v2.y;
|
||||||
|
ret += v1.z*v2.z;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec3f_norm(vec3f v)
|
||||||
|
{
|
||||||
|
float ret = ::sqrtf(v.x*v.x+v.y*v.y+v.z*v.z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f_normalize(vec3f v)
|
||||||
|
{
|
||||||
|
vec3f ret = vec3f(0,0,0);
|
||||||
|
float nrm = vec3f_norm(v);
|
||||||
|
if(nrm>0.0)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec3f_dist(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
return vec3f_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f_cross(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
ret[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||||
|
ret[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||||
|
ret[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vec3f_proj(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
vec3f ret;
|
||||||
|
vec3f v2n = vec3f_normalize(v2);
|
||||||
|
ret = v2n*vec3f_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f vec3f_hodgedual(vec3f v)
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
|
||||||
|
ret(0,1) = v[2];
|
||||||
|
ret(1,2) = v[0];
|
||||||
|
ret(2,0) = v[1];
|
||||||
|
|
||||||
|
ret(1,0) = -v[2];
|
||||||
|
ret(2,1) = -v[0];
|
||||||
|
ret(0,2) = -v[1];
|
||||||
|
|
||||||
|
ret(0,0) = 0.0;
|
||||||
|
ret(1,1) = 0.0;
|
||||||
|
ret(2,2) = 0.0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (old nomenclature)
|
||||||
|
float vdot(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
return vec3f_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vnorm(vec3f v)
|
||||||
|
{
|
||||||
|
return vec3f_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vnormalize(vec3f v)
|
||||||
|
{
|
||||||
|
return vec3f_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vdist(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
return vec3f_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vcross(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
return vec3f_cross(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f vproj(vec3f v1, vec3f v2)
|
||||||
|
{
|
||||||
|
return vec3f_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3f constructors
|
||||||
|
mat3f::mat3f()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f::mat3f(float _xx, float _yx, float _zx, float _xy, float _yy, float _zy, float _xz, float _yz, float _zz)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _zx;
|
||||||
|
|
||||||
|
data[3] = _xy;
|
||||||
|
data[4] = _yy;
|
||||||
|
data[5] = _zy;
|
||||||
|
|
||||||
|
data[6] = _xz;
|
||||||
|
data[7] = _yz;
|
||||||
|
data[8] = _zz;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f::mat3f(const float *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = _data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f::mat3f(const mat3f &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = rhs.data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f::mat3f(const vec3f _col1, const vec3f _col2, const vec3f _col3)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col1[2];
|
||||||
|
|
||||||
|
data[3] = _col2[0];
|
||||||
|
data[4] = _col2[1];
|
||||||
|
data[5] = _col2[2];
|
||||||
|
|
||||||
|
data[6] = _col3[0];
|
||||||
|
data[7] = _col3[1];
|
||||||
|
data[8] = _col3[2];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3f assignment and comparison operators
|
||||||
|
mat3f& mat3f::operator=(const mat3f rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) data[I] = rhs.data[I];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat3f::operator==(const mat3f rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
if(this->data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3f arithmetic operators
|
||||||
|
mat3f mat3f::operator+(mat3f rhs) const
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::operator-(mat3f rhs) const
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::operator*(mat3f rhs) const
|
||||||
|
{
|
||||||
|
mat3f ret = mat3f_zeros();
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
for(K=0;K<3;K++)
|
||||||
|
ret(I,K) += + (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::operator/(mat3f rhs) const
|
||||||
|
{
|
||||||
|
mat3f rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f mat3f::operator*(vec3f rhs) const
|
||||||
|
{
|
||||||
|
vec3f ret = vec3f(0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3f access operators
|
||||||
|
float& mat3f::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat3f::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat3f::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat3f::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat3f::at(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat3f::at(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 3*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat3f member functions
|
||||||
|
float mat3f::det()
|
||||||
|
{
|
||||||
|
float ret = 0.0;
|
||||||
|
ret += (*this)(0,0)*(*this)(1,1)*(*this)(2,2);
|
||||||
|
ret += (*this)(0,1)*(*this)(1,2)*(*this)(2,0);
|
||||||
|
ret += (*this)(0,2)*(*this)(1,0)*(*this)(2,1);
|
||||||
|
|
||||||
|
ret -= (*this)(2,0)*(*this)(1,1)*(*this)(0,2);
|
||||||
|
ret -= (*this)(2,1)*(*this)(1,2)*(*this)(0,0);
|
||||||
|
ret -= (*this)(2,2)*(*this)(1,0)*(*this)(0,1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::inverse()
|
||||||
|
{
|
||||||
|
mat3f ret = mat3f_zeros();
|
||||||
|
float dt = this->det();
|
||||||
|
if(dt>vecmat_det_small||dt<-vecmat_det_small)
|
||||||
|
{
|
||||||
|
ret(0,0) = (this->at(1,1) * this->at(2,2) - this->at(1,2) * this->at(2,1))/dt;
|
||||||
|
ret(0,1) = -(this->at(1,0) * this->at(2,2) - this->at(1,2) * this->at(2,0))/dt;
|
||||||
|
ret(0,2) = (this->at(1,0) * this->at(2,1) - this->at(1,1) * this->at(2,0))/dt;
|
||||||
|
ret(1,0) = -(this->at(0,1) * this->at(2,2) - this->at(0,2) * this->at(2,1))/dt;
|
||||||
|
ret(1,1) = (this->at(0,0) * this->at(2,2) - this->at(0,2) * this->at(2,0))/dt;
|
||||||
|
ret(1,2) = -(this->at(0,0) * this->at(2,1) - this->at(0,1) * this->at(2,0))/dt;
|
||||||
|
ret(2,0) = (this->at(0,1) * this->at(1,2) - this->at(0,2) * this->at(1,1))/dt;
|
||||||
|
ret(2,1) = -(this->at(0,0) * this->at(1,2) - this->at(0,2) * this->at(1,0))/dt;
|
||||||
|
ret(2,2) = (this->at(0,0) * this->at(1,1) - this->at(0,1) * this->at(1,0))/dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat3f::invert()
|
||||||
|
{
|
||||||
|
mat3f m = this->inverse();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f::transpose()
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat3f::dotranspose()
|
||||||
|
{
|
||||||
|
mat3f m = this->transpose();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// matrix operations (standalone functions)
|
||||||
|
mat3f mat3f_eye()
|
||||||
|
{
|
||||||
|
mat3f ret = mat3f_zeros();
|
||||||
|
ret(0,0) = 1.0;
|
||||||
|
ret(1,1) = 1.0;
|
||||||
|
ret(2,2) = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f_zeros()
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
// for speed - the constructor already sets data[I] to 0.0
|
||||||
|
// int I;
|
||||||
|
// for(I=0;I<9;I++) ret.data[I] = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f_ones()
|
||||||
|
{
|
||||||
|
mat3f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<9;I++) ret.data[I] = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f_mult(mat3f a, mat3f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f mat3f_mult(vec3f a, mat3f b)
|
||||||
|
{
|
||||||
|
vec3f ret = vec3f(0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<3;I++)
|
||||||
|
for(J=0;J<3;J++)
|
||||||
|
ret[J] += a[I] * b(I,J);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3f mat3f_mult(mat3f a, vec3f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mat3f_det(mat3f a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f_inverse(mat3f a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3f mat3f_transpose(mat3f a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,615 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
// vec4 constructors
|
||||||
|
vec4::vec4()
|
||||||
|
{
|
||||||
|
x = 0.0;
|
||||||
|
y = 0.0;
|
||||||
|
z = 0.0;
|
||||||
|
w = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4::vec4(double _x, double _y, double _z, double _w)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
z = _z;
|
||||||
|
w = _w;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4::vec4(const vec4 &rhs)
|
||||||
|
{
|
||||||
|
x = rhs.x;
|
||||||
|
y = rhs.y;
|
||||||
|
z = rhs.z;
|
||||||
|
w = rhs.w;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4 assignment and comparison operators
|
||||||
|
vec4& vec4::operator=(const vec4 &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
this->z = rhs.z;
|
||||||
|
this->w = rhs.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec4::operator==(vec4 rhs)
|
||||||
|
{
|
||||||
|
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z) && (this->w == rhs.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4 arithmetic operators
|
||||||
|
vec4 vec4::operator+(vec4 rhs) const
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
ret.z = this->z + rhs.z;
|
||||||
|
ret.w = this->w + rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4::operator-(vec4 rhs) const
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
ret.z = this->z - rhs.z;
|
||||||
|
ret.w = this->w - rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
ret.z = this->z*rhs;
|
||||||
|
ret.w = this->w*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
ret.z = this->z/rhs;
|
||||||
|
ret.w = this->w/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 operator-(vec4 rhs)
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
ret.z = -rhs.z;
|
||||||
|
ret.w = -rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4 subscript operators
|
||||||
|
double& vec4::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
else if(ind==3) return w;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& vec4::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
else if(ind==3) return w;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (new nomenclature)
|
||||||
|
double vec4_dot(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
ret += v1.x*v2.x;
|
||||||
|
ret += v1.y*v2.y;
|
||||||
|
ret += v1.z*v2.z;
|
||||||
|
ret += v1.w*v2.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec4_norm(vec4 v)
|
||||||
|
{
|
||||||
|
double ret = ::sqrt(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4_normalize(vec4 v)
|
||||||
|
{
|
||||||
|
vec4 ret = vec4(0,0,0,0);
|
||||||
|
double nrm = vec4_norm(v);
|
||||||
|
if(nrm>0.0)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double vec4_dist(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
return vec4_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vec4_proj(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
vec4 ret;
|
||||||
|
vec4 v2n = vec4_normalize(v2);
|
||||||
|
ret = v2n*vec4_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (old nomenclature)
|
||||||
|
double vdot(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
return vec4_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vnorm(vec4 v)
|
||||||
|
{
|
||||||
|
return vec4_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vnormalize(vec4 v)
|
||||||
|
{
|
||||||
|
return vec4_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
double vdist(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
return vec4_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 vproj(vec4 v1, vec4 v2)
|
||||||
|
{
|
||||||
|
return vec4_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4 constructors
|
||||||
|
mat4::mat4()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4::mat4(
|
||||||
|
double _xx, double _yx, double _zx, double _wx,
|
||||||
|
double _xy, double _yy, double _zy, double _wy,
|
||||||
|
double _xz, double _yz, double _zz, double _wz,
|
||||||
|
double _xw, double _yw, double _zw, double _ww
|
||||||
|
)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _zx;
|
||||||
|
data[3] = _wx;
|
||||||
|
|
||||||
|
data[4] = _xy;
|
||||||
|
data[5] = _yy;
|
||||||
|
data[6] = _zy;
|
||||||
|
data[7] = _wy;
|
||||||
|
|
||||||
|
data[8] = _xz;
|
||||||
|
data[9] = _yz;
|
||||||
|
data[10] = _zz;
|
||||||
|
data[11] = _wz;
|
||||||
|
|
||||||
|
data[12] = _xw;
|
||||||
|
data[13] = _yw;
|
||||||
|
data[14] = _zw;
|
||||||
|
data[15] = _ww;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4::mat4(const double *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = _data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4::mat4(const mat4 &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = rhs.data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4::mat4(const vec4 _col1, const vec4 _col2, const vec4 _col3, const vec4 _col4)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col1[2];
|
||||||
|
data[3] = _col1[3];
|
||||||
|
|
||||||
|
data[4] = _col2[0];
|
||||||
|
data[5] = _col2[1];
|
||||||
|
data[6] = _col2[2];
|
||||||
|
data[7] = _col2[3];
|
||||||
|
|
||||||
|
data[8] = _col3[0];
|
||||||
|
data[9] = _col3[1];
|
||||||
|
data[10] = _col3[2];
|
||||||
|
data[11] = _col3[3];
|
||||||
|
|
||||||
|
data[12] = _col4[0];
|
||||||
|
data[13] = _col4[1];
|
||||||
|
data[14] = _col4[2];
|
||||||
|
data[15] = _col4[3];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4 assignment and comparison operators
|
||||||
|
mat4& mat4::operator=(const mat4 rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = rhs.data[I];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat4::operator==(const mat4 rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
if(this->data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4 arithmetic operators
|
||||||
|
mat4 mat4::operator+(mat4 rhs) const
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::operator-(mat4 rhs) const
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::operator*(mat4 rhs) const
|
||||||
|
{
|
||||||
|
mat4 ret = mat4_zeros();
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
for(K=0;K<4;K++)
|
||||||
|
ret(I,K) += (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::operator/(mat4 rhs) const
|
||||||
|
{
|
||||||
|
mat4 rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::operator*(double rhs) const
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::operator/(double rhs) const
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mat4::operator*(vec4 rhs) const
|
||||||
|
{
|
||||||
|
vec4 ret = vec4(0,0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4 access operators
|
||||||
|
double& mat4::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat4::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat4::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat4::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
double& mat4::at(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& mat4::at(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
double mat4::det()
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
double a00,a01,a02,a03;
|
||||||
|
double a10,a11,a12,a13;
|
||||||
|
double a20,a21,a22,a23;
|
||||||
|
double a30,a31,a32,a33;
|
||||||
|
|
||||||
|
a00 = this->at(0,0);
|
||||||
|
a01 = this->at(0,1);
|
||||||
|
a02 = this->at(0,2);
|
||||||
|
a03 = this->at(0,3);
|
||||||
|
a10 = this->at(1,0);
|
||||||
|
a11 = this->at(1,1);
|
||||||
|
a12 = this->at(1,2);
|
||||||
|
a13 = this->at(1,3);
|
||||||
|
a20 = this->at(2,0);
|
||||||
|
a21 = this->at(2,1);
|
||||||
|
a22 = this->at(2,2);
|
||||||
|
a23 = this->at(2,3);
|
||||||
|
a30 = this->at(3,0);
|
||||||
|
a31 = this->at(3,1);
|
||||||
|
a32 = this->at(3,2);
|
||||||
|
a33 = this->at(3,3);
|
||||||
|
|
||||||
|
ret = a03*a12*a21*a30 -
|
||||||
|
a02*a13*a21*a30 -
|
||||||
|
a03*a11*a22*a30 +
|
||||||
|
a01*a13*a22*a30 +
|
||||||
|
a02*a11*a23*a30 -
|
||||||
|
a01*a12*a23*a30 -
|
||||||
|
a03*a12*a20*a31 +
|
||||||
|
a02*a13*a20*a31 +
|
||||||
|
a03*a10*a22*a31 -
|
||||||
|
a00*a13*a22*a31 -
|
||||||
|
a02*a10*a23*a31 +
|
||||||
|
a00*a12*a23*a31 +
|
||||||
|
a03*a11*a20*a32 -
|
||||||
|
a01*a13*a20*a32 -
|
||||||
|
a03*a10*a21*a32 +
|
||||||
|
a00*a13*a21*a32 +
|
||||||
|
a01*a10*a23*a32 -
|
||||||
|
a00*a11*a23*a32 -
|
||||||
|
a02*a11*a20*a33 +
|
||||||
|
a01*a12*a20*a33 +
|
||||||
|
a02*a10*a21*a33 -
|
||||||
|
a00*a12*a21*a33 -
|
||||||
|
a01*a10*a22*a33 +
|
||||||
|
a00*a11*a22*a33;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::inverse()
|
||||||
|
{
|
||||||
|
mat4 ret = mat4_zeros();
|
||||||
|
double dt = this->det();
|
||||||
|
|
||||||
|
double a00,a01,a02,a03;
|
||||||
|
double a10,a11,a12,a13;
|
||||||
|
double a20,a21,a22,a23;
|
||||||
|
double a30,a31,a32,a33;
|
||||||
|
|
||||||
|
double b00,b01,b02,b03;
|
||||||
|
double b10,b11,b12,b13;
|
||||||
|
double b20,b21,b22,b23;
|
||||||
|
double b30,b31,b32,b33;
|
||||||
|
|
||||||
|
a00 = this->at(0,0);
|
||||||
|
a01 = this->at(0,1);
|
||||||
|
a02 = this->at(0,2);
|
||||||
|
a03 = this->at(0,3);
|
||||||
|
a10 = this->at(1,0);
|
||||||
|
a11 = this->at(1,1);
|
||||||
|
a12 = this->at(1,2);
|
||||||
|
a13 = this->at(1,3);
|
||||||
|
a20 = this->at(2,0);
|
||||||
|
a21 = this->at(2,1);
|
||||||
|
a22 = this->at(2,2);
|
||||||
|
a23 = this->at(2,3);
|
||||||
|
a30 = this->at(3,0);
|
||||||
|
a31 = this->at(3,1);
|
||||||
|
a32 = this->at(3,2);
|
||||||
|
a33 = this->at(3,3);
|
||||||
|
|
||||||
|
if(ams::abs(dt)>vecmat_det_small)
|
||||||
|
{
|
||||||
|
b00 = -a13*a22*a31 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 + a11*a22*a33;
|
||||||
|
b01 = a03*a22*a31 - a02*a23*a31 - a03*a21*a32 + a01*a23*a32 + a02*a21*a33 - a01*a22*a33;
|
||||||
|
b02 = -a03*a12*a31 + a02*a13*a31 + a03*a11*a32 - a01*a13*a32 - a02*a11*a33 + a01*a12*a33;
|
||||||
|
b03 = a03*a12*a21 - a02*a13*a21 - a03*a11*a22 + a01*a13*a22 + a02*a11*a23 - a01*a12*a23;
|
||||||
|
b10 = a13*a22*a30 - a12*a23*a30 - a13*a20*a32 + a10*a23*a32 + a12*a20*a33 - a10*a22*a33;
|
||||||
|
b11 = -a03*a22*a30 + a02*a23*a30 + a03*a20*a32 - a00*a23*a32 - a02*a20*a33 + a00*a22*a33;
|
||||||
|
b12 = a03*a12*a30 - a02*a13*a30 - a03*a10*a32 + a00*a13*a32 + a02*a10*a33 - a00*a12*a33;
|
||||||
|
b13 = -a03*a12*a20 + a02*a13*a20 + a03*a10*a22 - a00*a13*a22 - a02*a10*a23 + a00*a12*a23;
|
||||||
|
b20 = -a13*a21*a30 + a11*a23*a30 + a13*a20*a31 - a10*a23*a31 - a11*a20*a33 + a10*a21*a33;
|
||||||
|
b21 = a03*a21*a30 - a01*a23*a30 - a03*a20*a31 + a00*a23*a31 + a01*a20*a33 - a00*a21*a33;
|
||||||
|
b22 = -a03*a11*a30 + a01*a13*a30 + a03*a10*a31 - a00*a13*a31 - a01*a10*a33 + a00*a11*a33;
|
||||||
|
b23 = a03*a11*a20 - a01*a13*a20 - a03*a10*a21 + a00*a13*a21 + a01*a10*a23 - a00*a11*a23;
|
||||||
|
b30 = a12*a21*a30 - a11*a22*a30 - a12*a20*a31 + a10*a22*a31 + a11*a20*a32 - a10*a21*a32;
|
||||||
|
b31 = -a02*a21*a30 + a01*a22*a30 + a02*a20*a31 - a00*a22*a31 - a01*a20*a32 + a00*a21*a32;
|
||||||
|
b32 = a02*a11*a30 - a01*a12*a30 - a02*a10*a31 + a00*a12*a31 + a01*a10*a32 - a00*a11*a32;
|
||||||
|
b33 = -a02*a11*a20 + a01*a12*a20 + a02*a10*a21 - a00*a12*a21 - a01*a10*a22 + a00*a11*a22;
|
||||||
|
b00 = b00/dt;
|
||||||
|
b01 = b01/dt;
|
||||||
|
b02 = b02/dt;
|
||||||
|
b03 = b03/dt;
|
||||||
|
b10 = b10/dt;
|
||||||
|
b11 = b11/dt;
|
||||||
|
b12 = b12/dt;
|
||||||
|
b13 = b13/dt;
|
||||||
|
b20 = b20/dt;
|
||||||
|
b21 = b21/dt;
|
||||||
|
b22 = b22/dt;
|
||||||
|
b23 = b23/dt;
|
||||||
|
b30 = b30/dt;
|
||||||
|
b31 = b31/dt;
|
||||||
|
b32 = b32/dt;
|
||||||
|
b33 = b33/dt;
|
||||||
|
ret(0,0) = b00;
|
||||||
|
ret(0,1) = b01;
|
||||||
|
ret(0,2) = b02;
|
||||||
|
ret(0,3) = b03;
|
||||||
|
ret(1,0) = b10;
|
||||||
|
ret(1,1) = b11;
|
||||||
|
ret(1,2) = b12;
|
||||||
|
ret(1,3) = b13;
|
||||||
|
ret(2,0) = b20;
|
||||||
|
ret(2,1) = b21;
|
||||||
|
ret(2,2) = b22;
|
||||||
|
ret(2,3) = b23;
|
||||||
|
ret(3,0) = b30;
|
||||||
|
ret(3,1) = b31;
|
||||||
|
ret(3,2) = b32;
|
||||||
|
ret(3,3) = b33;
|
||||||
|
}
|
||||||
|
//this was STUPID. Gaah. Computer algebra system saves the day? I'd be surprised if this didn't end up *slower* than gaussian elimination. Don't do this again!
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat4::invert()
|
||||||
|
{
|
||||||
|
mat4 m = this->inverse();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4::transpose()
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat4::dotranspose()
|
||||||
|
{
|
||||||
|
mat4 m = this->transpose();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// matrix operations (standalone functions)
|
||||||
|
mat4 mat4_eye()
|
||||||
|
{
|
||||||
|
mat4 ret = mat4_zeros();
|
||||||
|
ret(0,0) = 1.0;
|
||||||
|
ret(1,1) = 1.0;
|
||||||
|
ret(2,2) = 1.0;
|
||||||
|
ret(3,3) = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4_zeros()
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
// for speed - the constructor already sets data[I] to 0.0
|
||||||
|
// int I;
|
||||||
|
// for(I=0;I<16;I++) ret.data[I] = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4_ones()
|
||||||
|
{
|
||||||
|
mat4 ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = 1.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4_mult(mat4 a, mat4 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mat4_mult(vec4 a, mat4 b)
|
||||||
|
{
|
||||||
|
vec4 ret = vec4(0,0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret[J] += a[I] * b(I,J);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mat4_mult(mat4 a, vec4 b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mat4_det(mat4 a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4_inverse(mat4 a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mat4_transpose(mat4 a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,615 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
|
||||||
|
// vec4f constructors
|
||||||
|
vec4f::vec4f()
|
||||||
|
{
|
||||||
|
x = 0.0f;
|
||||||
|
y = 0.0f;
|
||||||
|
z = 0.0f;
|
||||||
|
w = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f::vec4f(float _x, float _y, float _z, float _w)
|
||||||
|
{
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
z = _z;
|
||||||
|
w = _w;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f::vec4f(const vec4f &rhs)
|
||||||
|
{
|
||||||
|
x = rhs.x;
|
||||||
|
y = rhs.y;
|
||||||
|
z = rhs.z;
|
||||||
|
w = rhs.w;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4f assignment and comparison operators
|
||||||
|
vec4f& vec4f::operator=(const vec4f &rhs)
|
||||||
|
{
|
||||||
|
this->x = rhs.x;
|
||||||
|
this->y = rhs.y;
|
||||||
|
this->z = rhs.z;
|
||||||
|
this->w = rhs.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec4f::operator==(vec4f rhs)
|
||||||
|
{
|
||||||
|
return ((this->x == rhs.x) && (this->y == rhs.y) && (this->z == rhs.z) && (this->w == rhs.w));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4f arithmetic operators
|
||||||
|
vec4f vec4f::operator+(vec4f rhs) const
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
ret.x = this->x + rhs.x;
|
||||||
|
ret.y = this->y + rhs.y;
|
||||||
|
ret.z = this->z + rhs.z;
|
||||||
|
ret.w = this->w + rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vec4f::operator-(vec4f rhs) const
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
ret.x = this->x - rhs.x;
|
||||||
|
ret.y = this->y - rhs.y;
|
||||||
|
ret.z = this->z - rhs.z;
|
||||||
|
ret.w = this->w - rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vec4f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
ret.x = this->x*rhs;
|
||||||
|
ret.y = this->y*rhs;
|
||||||
|
ret.z = this->z*rhs;
|
||||||
|
ret.w = this->w*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vec4f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
ret.x = this->x/rhs;
|
||||||
|
ret.y = this->y/rhs;
|
||||||
|
ret.z = this->z/rhs;
|
||||||
|
ret.w = this->w/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f operator-(vec4f rhs)
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
ret.x = -rhs.x;
|
||||||
|
ret.y = -rhs.y;
|
||||||
|
ret.z = -rhs.z;
|
||||||
|
ret.w = -rhs.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec4f subscript operators
|
||||||
|
float& vec4f::operator[](int ind)
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
else if(ind==3) return w;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& vec4f::operator[](int ind) const
|
||||||
|
{
|
||||||
|
if(ind==0) return x;
|
||||||
|
else if(ind==1) return y;
|
||||||
|
else if(ind==2) return z;
|
||||||
|
else if(ind==3) return w;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (new nomenclature)
|
||||||
|
float vec4f_dot(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
float ret = 0.0f;
|
||||||
|
ret += v1.x*v2.x;
|
||||||
|
ret += v1.y*v2.y;
|
||||||
|
ret += v1.z*v2.z;
|
||||||
|
ret += v1.w*v2.w;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec4f_norm(vec4f v)
|
||||||
|
{
|
||||||
|
float ret = ::sqrtf(v.x*v.x+v.y*v.y+v.z*v.z+v.w*v.w);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vec4f_normalize(vec4f v)
|
||||||
|
{
|
||||||
|
vec4f ret = vec4f(0,0,0,0);
|
||||||
|
float nrm = vec4f_norm(v);
|
||||||
|
if(nrm>0.0)
|
||||||
|
{
|
||||||
|
ret = v/nrm;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float vec4f_dist(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
return vec4f_norm(v1-v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vec4f_proj(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
vec4f ret;
|
||||||
|
vec4f v2n = vec4f_normalize(v2);
|
||||||
|
ret = v2n*vec4f_dot(v1,v2n);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vector operations (old nomenclature)
|
||||||
|
float vdot(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
return vec4f_dot(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vnorm(vec4f v)
|
||||||
|
{
|
||||||
|
return vec4f_norm(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vnormalize(vec4f v)
|
||||||
|
{
|
||||||
|
return vec4f_normalize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float vdist(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
return vec4f_dist(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f vproj(vec4f v1, vec4f v2)
|
||||||
|
{
|
||||||
|
return vec4f_proj(v1,v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4f constructors
|
||||||
|
mat4f::mat4f()
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f::mat4f(
|
||||||
|
float _xx, float _yx, float _zx, float _wx,
|
||||||
|
float _xy, float _yy, float _zy, float _wy,
|
||||||
|
float _xz, float _yz, float _zz, float _wz,
|
||||||
|
float _xw, float _yw, float _zw, float _ww
|
||||||
|
)
|
||||||
|
{
|
||||||
|
data[0] = _xx;
|
||||||
|
data[1] = _yx;
|
||||||
|
data[2] = _zx;
|
||||||
|
data[3] = _wx;
|
||||||
|
|
||||||
|
data[4] = _xy;
|
||||||
|
data[5] = _yy;
|
||||||
|
data[6] = _zy;
|
||||||
|
data[7] = _wy;
|
||||||
|
|
||||||
|
data[8] = _xz;
|
||||||
|
data[9] = _yz;
|
||||||
|
data[10] = _zz;
|
||||||
|
data[11] = _wz;
|
||||||
|
|
||||||
|
data[12] = _xw;
|
||||||
|
data[13] = _yw;
|
||||||
|
data[14] = _zw;
|
||||||
|
data[15] = _ww;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f::mat4f(const float *_data)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = _data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f::mat4f(const mat4f &rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = rhs.data[I];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f::mat4f(const vec4f _col1, const vec4f _col2, const vec4f _col3, const vec4f _col4)
|
||||||
|
{
|
||||||
|
data[0] = _col1[0];
|
||||||
|
data[1] = _col1[1];
|
||||||
|
data[2] = _col1[2];
|
||||||
|
data[3] = _col1[3];
|
||||||
|
|
||||||
|
data[4] = _col2[0];
|
||||||
|
data[5] = _col2[1];
|
||||||
|
data[6] = _col2[2];
|
||||||
|
data[7] = _col2[3];
|
||||||
|
|
||||||
|
data[8] = _col3[0];
|
||||||
|
data[9] = _col3[1];
|
||||||
|
data[10] = _col3[2];
|
||||||
|
data[11] = _col3[3];
|
||||||
|
|
||||||
|
data[12] = _col4[0];
|
||||||
|
data[13] = _col4[1];
|
||||||
|
data[14] = _col4[2];
|
||||||
|
data[15] = _col4[3];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4f assignment and comparison operators
|
||||||
|
mat4f& mat4f::operator=(const mat4f rhs)
|
||||||
|
{
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) data[I] = rhs.data[I];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mat4f::operator==(const mat4f rhs)
|
||||||
|
{
|
||||||
|
bool ret = 1;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
if(this->data[I]!=rhs.data[I])
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4f arithmetic operators
|
||||||
|
mat4f mat4f::operator+(mat4f rhs) const
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] + rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::operator-(mat4f rhs) const
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++)
|
||||||
|
{
|
||||||
|
ret.data[I] = this->data[I] - rhs.data[I];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::operator*(mat4f rhs) const
|
||||||
|
{
|
||||||
|
mat4f ret = mat4f_zeros();
|
||||||
|
int I,J,K;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
for(K=0;K<4;K++)
|
||||||
|
ret(I,K) += (*this)(I,J)*rhs(J,K);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::operator/(mat4f rhs) const
|
||||||
|
{
|
||||||
|
mat4f rhsi = rhs.inverse();
|
||||||
|
return (*this)*rhsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::operator*(float rhs) const
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = this->data[I]*rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::operator/(float rhs) const
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = this->data[I]/rhs;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f mat4f::operator*(vec4f rhs) const
|
||||||
|
{
|
||||||
|
vec4f ret = vec4f(0,0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret[I] += (*this)(I,J)*rhs[J];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mat4f access operators
|
||||||
|
float& mat4f::operator()(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat4f::operator[](int I)
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat4f::operator()(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat4f::operator[](int I) const
|
||||||
|
{
|
||||||
|
return data[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
float& mat4f::at(int I, int J)
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& mat4f::at(int I, int J) const
|
||||||
|
{
|
||||||
|
int ind = I + 4*J;
|
||||||
|
return data[ind];
|
||||||
|
}
|
||||||
|
|
||||||
|
float mat4f::det()
|
||||||
|
{
|
||||||
|
float ret = 0.0f;
|
||||||
|
float a00,a01,a02,a03;
|
||||||
|
float a10,a11,a12,a13;
|
||||||
|
float a20,a21,a22,a23;
|
||||||
|
float a30,a31,a32,a33;
|
||||||
|
|
||||||
|
a00 = this->at(0,0);
|
||||||
|
a01 = this->at(0,1);
|
||||||
|
a02 = this->at(0,2);
|
||||||
|
a03 = this->at(0,3);
|
||||||
|
a10 = this->at(1,0);
|
||||||
|
a11 = this->at(1,1);
|
||||||
|
a12 = this->at(1,2);
|
||||||
|
a13 = this->at(1,3);
|
||||||
|
a20 = this->at(2,0);
|
||||||
|
a21 = this->at(2,1);
|
||||||
|
a22 = this->at(2,2);
|
||||||
|
a23 = this->at(2,3);
|
||||||
|
a30 = this->at(3,0);
|
||||||
|
a31 = this->at(3,1);
|
||||||
|
a32 = this->at(3,2);
|
||||||
|
a33 = this->at(3,3);
|
||||||
|
|
||||||
|
ret = a03*a12*a21*a30 -
|
||||||
|
a02*a13*a21*a30 -
|
||||||
|
a03*a11*a22*a30 +
|
||||||
|
a01*a13*a22*a30 +
|
||||||
|
a02*a11*a23*a30 -
|
||||||
|
a01*a12*a23*a30 -
|
||||||
|
a03*a12*a20*a31 +
|
||||||
|
a02*a13*a20*a31 +
|
||||||
|
a03*a10*a22*a31 -
|
||||||
|
a00*a13*a22*a31 -
|
||||||
|
a02*a10*a23*a31 +
|
||||||
|
a00*a12*a23*a31 +
|
||||||
|
a03*a11*a20*a32 -
|
||||||
|
a01*a13*a20*a32 -
|
||||||
|
a03*a10*a21*a32 +
|
||||||
|
a00*a13*a21*a32 +
|
||||||
|
a01*a10*a23*a32 -
|
||||||
|
a00*a11*a23*a32 -
|
||||||
|
a02*a11*a20*a33 +
|
||||||
|
a01*a12*a20*a33 +
|
||||||
|
a02*a10*a21*a33 -
|
||||||
|
a00*a12*a21*a33 -
|
||||||
|
a01*a10*a22*a33 +
|
||||||
|
a00*a11*a22*a33;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::inverse()
|
||||||
|
{
|
||||||
|
mat4f ret = mat4f_zeros();
|
||||||
|
float dt = this->det();
|
||||||
|
|
||||||
|
float a00,a01,a02,a03;
|
||||||
|
float a10,a11,a12,a13;
|
||||||
|
float a20,a21,a22,a23;
|
||||||
|
float a30,a31,a32,a33;
|
||||||
|
|
||||||
|
float b00,b01,b02,b03;
|
||||||
|
float b10,b11,b12,b13;
|
||||||
|
float b20,b21,b22,b23;
|
||||||
|
float b30,b31,b32,b33;
|
||||||
|
|
||||||
|
a00 = this->at(0,0);
|
||||||
|
a01 = this->at(0,1);
|
||||||
|
a02 = this->at(0,2);
|
||||||
|
a03 = this->at(0,3);
|
||||||
|
a10 = this->at(1,0);
|
||||||
|
a11 = this->at(1,1);
|
||||||
|
a12 = this->at(1,2);
|
||||||
|
a13 = this->at(1,3);
|
||||||
|
a20 = this->at(2,0);
|
||||||
|
a21 = this->at(2,1);
|
||||||
|
a22 = this->at(2,2);
|
||||||
|
a23 = this->at(2,3);
|
||||||
|
a30 = this->at(3,0);
|
||||||
|
a31 = this->at(3,1);
|
||||||
|
a32 = this->at(3,2);
|
||||||
|
a33 = this->at(3,3);
|
||||||
|
|
||||||
|
if(ams::abs(dt)>vecmat_det_small)
|
||||||
|
{
|
||||||
|
b00 = -a13*a22*a31 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 + a11*a22*a33;
|
||||||
|
b01 = a03*a22*a31 - a02*a23*a31 - a03*a21*a32 + a01*a23*a32 + a02*a21*a33 - a01*a22*a33;
|
||||||
|
b02 = -a03*a12*a31 + a02*a13*a31 + a03*a11*a32 - a01*a13*a32 - a02*a11*a33 + a01*a12*a33;
|
||||||
|
b03 = a03*a12*a21 - a02*a13*a21 - a03*a11*a22 + a01*a13*a22 + a02*a11*a23 - a01*a12*a23;
|
||||||
|
b10 = a13*a22*a30 - a12*a23*a30 - a13*a20*a32 + a10*a23*a32 + a12*a20*a33 - a10*a22*a33;
|
||||||
|
b11 = -a03*a22*a30 + a02*a23*a30 + a03*a20*a32 - a00*a23*a32 - a02*a20*a33 + a00*a22*a33;
|
||||||
|
b12 = a03*a12*a30 - a02*a13*a30 - a03*a10*a32 + a00*a13*a32 + a02*a10*a33 - a00*a12*a33;
|
||||||
|
b13 = -a03*a12*a20 + a02*a13*a20 + a03*a10*a22 - a00*a13*a22 - a02*a10*a23 + a00*a12*a23;
|
||||||
|
b20 = -a13*a21*a30 + a11*a23*a30 + a13*a20*a31 - a10*a23*a31 - a11*a20*a33 + a10*a21*a33;
|
||||||
|
b21 = a03*a21*a30 - a01*a23*a30 - a03*a20*a31 + a00*a23*a31 + a01*a20*a33 - a00*a21*a33;
|
||||||
|
b22 = -a03*a11*a30 + a01*a13*a30 + a03*a10*a31 - a00*a13*a31 - a01*a10*a33 + a00*a11*a33;
|
||||||
|
b23 = a03*a11*a20 - a01*a13*a20 - a03*a10*a21 + a00*a13*a21 + a01*a10*a23 - a00*a11*a23;
|
||||||
|
b30 = a12*a21*a30 - a11*a22*a30 - a12*a20*a31 + a10*a22*a31 + a11*a20*a32 - a10*a21*a32;
|
||||||
|
b31 = -a02*a21*a30 + a01*a22*a30 + a02*a20*a31 - a00*a22*a31 - a01*a20*a32 + a00*a21*a32;
|
||||||
|
b32 = a02*a11*a30 - a01*a12*a30 - a02*a10*a31 + a00*a12*a31 + a01*a10*a32 - a00*a11*a32;
|
||||||
|
b33 = -a02*a11*a20 + a01*a12*a20 + a02*a10*a21 - a00*a12*a21 - a01*a10*a22 + a00*a11*a22;
|
||||||
|
b00 = b00/dt;
|
||||||
|
b01 = b01/dt;
|
||||||
|
b02 = b02/dt;
|
||||||
|
b03 = b03/dt;
|
||||||
|
b10 = b10/dt;
|
||||||
|
b11 = b11/dt;
|
||||||
|
b12 = b12/dt;
|
||||||
|
b13 = b13/dt;
|
||||||
|
b20 = b20/dt;
|
||||||
|
b21 = b21/dt;
|
||||||
|
b22 = b22/dt;
|
||||||
|
b23 = b23/dt;
|
||||||
|
b30 = b30/dt;
|
||||||
|
b31 = b31/dt;
|
||||||
|
b32 = b32/dt;
|
||||||
|
b33 = b33/dt;
|
||||||
|
ret(0,0) = b00;
|
||||||
|
ret(0,1) = b01;
|
||||||
|
ret(0,2) = b02;
|
||||||
|
ret(0,3) = b03;
|
||||||
|
ret(1,0) = b10;
|
||||||
|
ret(1,1) = b11;
|
||||||
|
ret(1,2) = b12;
|
||||||
|
ret(1,3) = b13;
|
||||||
|
ret(2,0) = b20;
|
||||||
|
ret(2,1) = b21;
|
||||||
|
ret(2,2) = b22;
|
||||||
|
ret(2,3) = b23;
|
||||||
|
ret(3,0) = b30;
|
||||||
|
ret(3,1) = b31;
|
||||||
|
ret(3,2) = b32;
|
||||||
|
ret(3,3) = b33;
|
||||||
|
}
|
||||||
|
//this was STUPID. Gaah. Computer algebra system saves the day? I'd be surprised if this didn't end up *slower* than gaussian elimination. Don't do this again!
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat4f::invert()
|
||||||
|
{
|
||||||
|
mat4f m = this->inverse();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f::transpose()
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret(I,J) = this->at(J,I);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mat4f::dotranspose()
|
||||||
|
{
|
||||||
|
mat4f m = this->transpose();
|
||||||
|
*this = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
// matrix operations (standalone functions)
|
||||||
|
mat4f mat4f_eye()
|
||||||
|
{
|
||||||
|
mat4f ret = mat4f_zeros();
|
||||||
|
ret(0,0) = 1.0f;
|
||||||
|
ret(1,1) = 1.0f;
|
||||||
|
ret(2,2) = 1.0f;
|
||||||
|
ret(3,3) = 1.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f_zeros()
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
// for speed - the constructor already sets data[I] to 0.0
|
||||||
|
// int I;
|
||||||
|
// for(I=0;I<16;I++) ret.data[I] = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f_ones()
|
||||||
|
{
|
||||||
|
mat4f ret;
|
||||||
|
int I;
|
||||||
|
for(I=0;I<16;I++) ret.data[I] = 1.0f;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f_mult(mat4f a, mat4f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f mat4f_mult(vec4f a, mat4f b)
|
||||||
|
{
|
||||||
|
vec4f ret = vec4f(0,0,0,0);
|
||||||
|
int I,J;
|
||||||
|
for(I=0;I<4;I++)
|
||||||
|
for(J=0;J<4;J++)
|
||||||
|
ret[J] += a[I] * b(I,J);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4f mat4f_mult(mat4f a, vec4f b)
|
||||||
|
{
|
||||||
|
return a*b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mat4f_det(mat4f a)
|
||||||
|
{
|
||||||
|
return a.det();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f_inverse(mat4f a)
|
||||||
|
{
|
||||||
|
return a.inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4f mat4f_transpose(mat4f a)
|
||||||
|
{
|
||||||
|
return a.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,414 @@
|
|||||||
|
|
||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
namespace cmp
|
||||||
|
{
|
||||||
|
|
||||||
|
complex::complex()
|
||||||
|
{
|
||||||
|
//initcode
|
||||||
|
r = 0.0;
|
||||||
|
i = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex::complex(double _r, double _i)
|
||||||
|
{
|
||||||
|
r = _r; i = _i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex::complex(double _r)
|
||||||
|
{
|
||||||
|
r = _r; i = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex::complex(const complex &other)
|
||||||
|
{
|
||||||
|
r = other.r;
|
||||||
|
i = other.i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex& complex::operator=(const complex& other)
|
||||||
|
{
|
||||||
|
r = other.r;
|
||||||
|
i = other.i;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex& complex::operator=(const double other)
|
||||||
|
{
|
||||||
|
r = other;
|
||||||
|
i = 0.0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
double& complex::operator[](int& ind)
|
||||||
|
{
|
||||||
|
if(ind==0)
|
||||||
|
{
|
||||||
|
return this->r;
|
||||||
|
}
|
||||||
|
else if(ind==1)
|
||||||
|
{
|
||||||
|
return this->i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("complex::operator[] index %d out of bounds\n",ind);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& complex::operator[](const int& ind) const
|
||||||
|
{
|
||||||
|
if(ind==0)
|
||||||
|
{
|
||||||
|
return this->r;
|
||||||
|
}
|
||||||
|
else if(ind==1)
|
||||||
|
{
|
||||||
|
return this->i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("complex::operator[] index %d out of bounds\n",ind);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator+(const complex &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r+z.r;
|
||||||
|
cp.i = i+z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator-(const complex &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r-z.r;
|
||||||
|
cp.i = i-z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator*(const complex &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r * z.r - i * z.i;
|
||||||
|
cp.i = r * z.i + i * z.r;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator/(const complex &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = (r*z.r+i*z.i)/(z.r*z.r+z.i*z.i);
|
||||||
|
cp.i = (i*z.r-r*z.i)/(z.r*z.r+z.i*z.i);
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator+(const double &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r + z;
|
||||||
|
cp.i = i + 0.0;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator-(const double &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r - z;
|
||||||
|
cp.i = i - 0.0;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator*(const double &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r * z;
|
||||||
|
cp.i = i * z;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex complex::operator/(const double &z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r/z;
|
||||||
|
cp.i = i/z;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex operator-(const complex &z)
|
||||||
|
{
|
||||||
|
complex ret;
|
||||||
|
ret.r = -z.r;
|
||||||
|
ret.i = -z.i;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double complex::arg()
|
||||||
|
{
|
||||||
|
double ret = ams::arg(this->r,this->i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double complex::mag()
|
||||||
|
{
|
||||||
|
return ::sqrt(r*r+i*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::iszero()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(r==0.0 && i == 0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::isreal()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
// bool ret = 0;
|
||||||
|
// if(re>DSMALL||re<-DSMALL)
|
||||||
|
// {
|
||||||
|
// ret = 0;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ret = 1;
|
||||||
|
// }
|
||||||
|
if(i==0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::isimag()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(r==0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const complex complex::conj()
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = r;
|
||||||
|
cp.i = -i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
double real(complex z)
|
||||||
|
{
|
||||||
|
return z.r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double imag(complex z)
|
||||||
|
{
|
||||||
|
return z.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex conj(complex z)
|
||||||
|
{
|
||||||
|
complex cp;
|
||||||
|
cp.r = z.r;
|
||||||
|
cp.i = -z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex exp(complex z)
|
||||||
|
{
|
||||||
|
complex ret;
|
||||||
|
ret.r = ::exp(z.r)*::cos(z.i);
|
||||||
|
ret.i = ::exp(z.r)*::sin(z.i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
complex log(complex z)
|
||||||
|
{
|
||||||
|
complex ret;
|
||||||
|
ret.r = ::log(::sqrt(z.r*z.r+z.i*z.i));
|
||||||
|
ret.i = ams::arg(z.r,z.i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex cos(complex z)
|
||||||
|
{
|
||||||
|
complex ret = complex(0.0,0.0);
|
||||||
|
complex div = complex(2.0,0.0);
|
||||||
|
complex im1 = complex(0.0,1.0);
|
||||||
|
ret = (exp(im1*z)+exp(im1*(-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex sin(complex z)
|
||||||
|
{
|
||||||
|
complex ret = complex(0.0,0.0);
|
||||||
|
complex div = complex(0.0,2.0);
|
||||||
|
complex im1 = complex(0.0,1.0);
|
||||||
|
ret = (exp(im1*z)-exp(im1*(-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex cosh(complex z)
|
||||||
|
{
|
||||||
|
complex ret = complex(0.0,0.0);
|
||||||
|
complex div = complex(2.0,0.0);
|
||||||
|
|
||||||
|
ret = (exp(z)+exp((-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex sinh(complex z)
|
||||||
|
{
|
||||||
|
complex ret = complex(0.0,0.0);
|
||||||
|
complex div = complex(2.0,0.0);
|
||||||
|
|
||||||
|
ret = (exp(z)-exp(-z))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex tan(complex z)
|
||||||
|
{
|
||||||
|
return sin(z)/cos(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
complex tanh(complex z)
|
||||||
|
{
|
||||||
|
return sinh(z)/cosh(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
complex pow(complex z1, complex z2)
|
||||||
|
{
|
||||||
|
complex ret;
|
||||||
|
if(z1.mag()>DSMALL)
|
||||||
|
ret= ams::cmp::exp(z2*ams::cmp::log(z1));
|
||||||
|
else
|
||||||
|
ret = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
double abs(complex z)
|
||||||
|
{
|
||||||
|
return z.mag();
|
||||||
|
}
|
||||||
|
|
||||||
|
double arg(ams::cmp::complex z)
|
||||||
|
{
|
||||||
|
return ams::arg(z.r,z.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//comparison operators
|
||||||
|
bool complex::operator==(const complex &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if((z.r == this->r) && (z.i == this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::operator!=(const complex &z)
|
||||||
|
{
|
||||||
|
bool ret = !(*this == z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort first by real value, then by imaginary value
|
||||||
|
//this is done so that an ordering exists, as long as two values aren't equal
|
||||||
|
bool complex::operator>(const complex& z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(this->r > z.r)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
else if(this->r == z.r)
|
||||||
|
{
|
||||||
|
if(this->i > z.i)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::operator<(const complex& z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = !((*this>z) || *this==z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::operator>=(const complex &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = (*this==z) || (*this>z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::operator<=(const complex &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = (*this<z) || (*this==z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::isnan()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(ams::isnan(this->r) || ams::isnan(this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex::isinf()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
//calls math.h isinf()
|
||||||
|
if(::isinf(this->r) || ::isinf(this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex csgn(complex z)
|
||||||
|
{
|
||||||
|
double a;
|
||||||
|
complex ret = ams::cmp::complex(0,0);
|
||||||
|
if(z.r==0.0 && z.i==0.0)
|
||||||
|
{
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = ams::cmp::arg(z);
|
||||||
|
ret.r = ::cos(a);
|
||||||
|
ret.i = ::sin(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
};//end namespace cmp
|
||||||
|
};//end namespace ams
|
@ -0,0 +1,414 @@
|
|||||||
|
|
||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
namespace cmp
|
||||||
|
{
|
||||||
|
|
||||||
|
complex64::complex64()
|
||||||
|
{
|
||||||
|
//initcode
|
||||||
|
r = 0.0;
|
||||||
|
i = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64::complex64(float _r, float _i)
|
||||||
|
{
|
||||||
|
r = _r; i = _i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64::complex64(float _r)
|
||||||
|
{
|
||||||
|
r = _r; i = 0.0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64::complex64(const complex64 &other)
|
||||||
|
{
|
||||||
|
r = other.r;
|
||||||
|
i = other.i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64& complex64::operator=(const complex64& other)
|
||||||
|
{
|
||||||
|
r = other.r;
|
||||||
|
i = other.i;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64& complex64::operator=(const float other)
|
||||||
|
{
|
||||||
|
r = other;
|
||||||
|
i = 0.0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
float& complex64::operator[](int& ind)
|
||||||
|
{
|
||||||
|
if(ind==0)
|
||||||
|
{
|
||||||
|
return this->r;
|
||||||
|
}
|
||||||
|
else if(ind==1)
|
||||||
|
{
|
||||||
|
return this->i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("complex64::operator[] index %d out of bounds\n",ind);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const float& complex64::operator[](const int& ind) const
|
||||||
|
{
|
||||||
|
if(ind==0)
|
||||||
|
{
|
||||||
|
return this->r;
|
||||||
|
}
|
||||||
|
else if(ind==1)
|
||||||
|
{
|
||||||
|
return this->i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("complex64::operator[] index %d out of bounds\n",ind);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator+(const complex64 &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r+z.r;
|
||||||
|
cp.i = i+z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator-(const complex64 &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r-z.r;
|
||||||
|
cp.i = i-z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator*(const complex64 &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r * z.r - i * z.i;
|
||||||
|
cp.i = r * z.i + i * z.r;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator/(const complex64 &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = (r*z.r+i*z.i)/(z.r*z.r+z.i*z.i);
|
||||||
|
cp.i = (i*z.r-r*z.i)/(z.r*z.r+z.i*z.i);
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator+(const float &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r + z;
|
||||||
|
cp.i = i + 0.0;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator-(const float &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r - z;
|
||||||
|
cp.i = i - 0.0;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator*(const float &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r * z;
|
||||||
|
cp.i = i * z;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 complex64::operator/(const float &z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r/z;
|
||||||
|
cp.i = i/z;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 operator-(const complex64 &z)
|
||||||
|
{
|
||||||
|
complex64 ret;
|
||||||
|
ret.r = -z.r;
|
||||||
|
ret.i = -z.i;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float complex64::arg()
|
||||||
|
{
|
||||||
|
float ret = ams::arg(this->r,this->i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float complex64::mag()
|
||||||
|
{
|
||||||
|
return ::sqrtf(r*r+i*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::iszero()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(r==0.0 && i == 0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::isreal()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
// bool ret = 0;
|
||||||
|
// if(re>DSMALL||re<-DSMALL)
|
||||||
|
// {
|
||||||
|
// ret = 0;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// ret = 1;
|
||||||
|
// }
|
||||||
|
if(i==0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::isimag()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(r==0.0)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const complex64 complex64::conj()
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = r;
|
||||||
|
cp.i = -i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float real(complex64 z)
|
||||||
|
{
|
||||||
|
return z.r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float imag(complex64 z)
|
||||||
|
{
|
||||||
|
return z.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 conj(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 cp;
|
||||||
|
cp.r = z.r;
|
||||||
|
cp.i = -z.i;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 exp(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret;
|
||||||
|
ret.r = ::expf(z.r)*::cos(z.i);
|
||||||
|
ret.i = ::expf(z.r)*::sin(z.i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
complex64 log(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret;
|
||||||
|
ret.r = ::log(::sqrtf(z.r*z.r+z.i*z.i));
|
||||||
|
ret.i = ams::arg(z.r,z.i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 cos(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret = complex64(0.0,0.0);
|
||||||
|
complex64 div = complex64(2.0,0.0);
|
||||||
|
complex64 im1 = complex64(0.0,1.0);
|
||||||
|
ret = (exp(im1*z)+exp(im1*(-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 sin(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret = complex64(0.0,0.0);
|
||||||
|
complex64 div = complex64(0.0,2.0);
|
||||||
|
complex64 im1 = complex64(0.0,1.0);
|
||||||
|
ret = (exp(im1*z)-exp(im1*(-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 cosh(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret = complex64(0.0,0.0);
|
||||||
|
complex64 div = complex64(2.0,0.0);
|
||||||
|
|
||||||
|
ret = (exp(z)+exp((-z)))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 sinh(complex64 z)
|
||||||
|
{
|
||||||
|
complex64 ret = complex64(0.0,0.0);
|
||||||
|
complex64 div = complex64(2.0,0.0);
|
||||||
|
|
||||||
|
ret = (exp(z)-exp(-z))/div;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 tan(complex64 z)
|
||||||
|
{
|
||||||
|
return sin(z)/cos(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 tanh(complex64 z)
|
||||||
|
{
|
||||||
|
return sinh(z)/cosh(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 pow(complex64 z1, complex64 z2)
|
||||||
|
{
|
||||||
|
complex64 ret;
|
||||||
|
if(z1.mag()>DSMALL)
|
||||||
|
ret= ams::cmp::exp(z2*ams::cmp::log(z1));
|
||||||
|
else
|
||||||
|
ret = 0.0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float abs(complex64 z)
|
||||||
|
{
|
||||||
|
return z.mag();
|
||||||
|
}
|
||||||
|
|
||||||
|
float arg(ams::cmp::complex64 z)
|
||||||
|
{
|
||||||
|
return ams::arg(z.r,z.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//comparison operators
|
||||||
|
bool complex64::operator==(const complex64 &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if((z.r == this->r) && (z.i == this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::operator!=(const complex64 &z)
|
||||||
|
{
|
||||||
|
bool ret = !(*this == z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort first by real value, then by imaginary value
|
||||||
|
//this is done so that an ordering exists, as long as two values aren't equal
|
||||||
|
bool complex64::operator>(const complex64& z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(this->r > z.r)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
else if(this->r == z.r)
|
||||||
|
{
|
||||||
|
if(this->i > z.i)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::operator<(const complex64& z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = !((*this>z) || *this==z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::operator>=(const complex64 &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = (*this==z) || (*this>z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::operator<=(const complex64 &z)
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
ret = (*this<z) || (*this==z);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::isnan()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
if(ams::isnan(this->r) || ams::isnan(this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool complex64::isinf()
|
||||||
|
{
|
||||||
|
bool ret = 0;
|
||||||
|
//calls math.h isinf()
|
||||||
|
if(::isinf(this->r) || ::isinf(this->i))
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
complex64 csgn(complex64 z)
|
||||||
|
{
|
||||||
|
float a;
|
||||||
|
complex64 ret = ams::cmp::complex64(0,0);
|
||||||
|
if(z.r==0.0 && z.i==0.0)
|
||||||
|
{
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = ams::cmp::arg(z);
|
||||||
|
ret.r = ::cos(a);
|
||||||
|
ret.i = ::sin(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
};//end namespace cmp
|
||||||
|
};//end namespace ams
|
@ -0,0 +1,29 @@
|
|||||||
|
#include <amsmathutil25/amsmathutil25.hpp>
|
||||||
|
|
||||||
|
namespace ams
|
||||||
|
{
|
||||||
|
namespace rand
|
||||||
|
{
|
||||||
|
|
||||||
|
amsmu_randt1 dpr32_rseed;
|
||||||
|
amsmu_randt2 dpr64_rseed;
|
||||||
|
|
||||||
|
amsmu_randt1 dpr32_nextseed(amsmu_randt1 seed)
|
||||||
|
{
|
||||||
|
amsmu_randt1 sret = seed;
|
||||||
|
sret = ams::mod(sret*dpr32_mult1+dpr32_add1,dpr32_mod);
|
||||||
|
return sret;
|
||||||
|
}
|
||||||
|
|
||||||
|
amsmu_randt2 dpr64_nextseed(amsmu_randt2 seed)
|
||||||
|
{
|
||||||
|
amsmu_randt2 sret = seed;
|
||||||
|
sret = ams::mod(sret*dpr64_mult1+dpr64_add1,dpr64_mod);
|
||||||
|
return sret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue