⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quater.cpp

📁 basic mathematic classes used for math programming
💻 CPP
字号:
#include "mathclass.h"static m_real eps = 0.0001;
quater::quater(const quater& qua){

	for(int i=0;i<4;i++){
	
		p[i] = qua.p[i];
	}

}
quater operator-(quater const& a){    return quater( -a.p[0], -a.p[1], -a.p[2], -a.p[3] );}quater inverse(quater const& a){    return quater( a.p[0], -a.p[1], -a.p[2], -a.p[3] );}quater operator+ (quater const& a, quater const& b){    quater c;    for(int i = 0; i < 4; i++)        c.p[i] = a.p[i] + b.p[i];    return c;}quater operator- (quater const& a, quater const& b){    quater c;    for(int i = 0; i < 4; i++)        c.p[i] = a.p[i] - b.p[i];    return c;}quater operator* (m_real a, quater const& b){    quater c;    for(int i = 0; i < 4; i++)        c.p[i] = a * b.p[i];    return c;}quater operator* (quater const& a, m_real b){    quater c;    for(int i = 0; i < 4; i++)        c.p[i] = a.p[i] * b;    return c;}quater operator/ (quater const& a, m_real b) {    quater c;    for(int i = 0; i < 4; i++)        c.p[i] = a.p[i] / b;    return c;}m_real operator% (quater const& a, quater const& b){    m_real c = 0;    for(int i = 0; i < 4; i++)        c += a.p[i] * b.p[i];    return c;}quater operator* (quater const& a, quater const& b){    quater c;    c.p[0] = a.p[0]*b.p[0] - a.p[1]*b.p[1] - a.p[2]*b.p[2] - a.p[3]*b.p[3];    c.p[1] = a.p[0]*b.p[1] + a.p[1]*b.p[0] + a.p[2]*b.p[3] - a.p[3]*b.p[2];    c.p[2] = a.p[0]*b.p[2] + a.p[2]*b.p[0] + a.p[3]*b.p[1] - a.p[1]*b.p[3];    c.p[3] = a.p[0]*b.p[3] + a.p[3]*b.p[0] + a.p[1]*b.p[2] - a.p[2]*b.p[1];    return c;}
matrix
quater::getMatrix()
{
	matrix m;
    m_real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;

    s  = 2.0/length();
    xs = x() * s;  ys = y() * s;  zs = z() * s;
    wx = w() * xs; wy = w() * ys; wz = w() * zs;
    xx = x() * xs; xy = x() * ys; xz = x() * zs;
    yy = y() * ys; yz = y() * zs; zz = z() * zs;

	

    m[0][0] = 1.0 - (yy + zz);
    m[1][0] = xy - wz;
    m[2][0] = xz + wy;
    m[0][1] = xy + wz;
    m[1][1] = 1.0 - (xx + zz);
    m[2][1] = yz - wx;
    m[0][2] = xz - wy;
    m[1][2] = yz + wx;
    m[2][2] = 1.0 - (xx + yy);
/*

	// Liu Ren changes here.
	m[0][0] = 1.0 - (yy + zz);
    m[1][0] = xy + wz;
    m[2][0] = xz - wy;
    m[0][1] = xy - wz;
    m[1][1] = 1.0 - (xx + zz);
    m[2][1] = yz + wx;
    m[0][2] = xz + wy;
    m[1][2] = yz - wx;
    m[2][2] = 1.0 - (xx + yy);
*/
    return m;
}

quater& 
quater::operator=(const quater& qua){

	for(int i=0;i<4;i++){
	
		p[i] = qua.p[i];
	}

	return (*this);
}


void
quater::setMatrix( matrix const& m )
{
	
    quater q;

    m_real tr, s;
    int    i, j, k;
    static int next[3] = { 1, 2, 0 };

    tr = m.getValue(0,0) + m.getValue(1,1) + m.getValue(2,2);
    if ( tr > 0.0 )
    {
        s = sqrt( tr + 1.0 );
        q.p[0] = ( s * 0.5 );
        s = 0.5 / s;
        q.p[1] = ( m.getValue(1,2) - m.getValue(2,1) ) * s;
        q.p[2] = ( m.getValue(2,0) - m.getValue(0,2) ) * s;
        q.p[3] = ( m.getValue(0,1) - m.getValue(1,0) ) * s;
    }
    else
    {
        i = 0;
        if ( m.getValue(1,1) > m.getValue(0,0) ) i = 1;
        if ( m.getValue(2,2) > m.getValue(i,i) ) i = 2;

        j = next[i];
        k = next[j];

        s = sqrt( (m.getValue(i,i)
					- (m.getValue(j,j) + m.getValue(k,k))) + 1.0 );
        q.p[i+1] = s * 0.5;
        s = 0.5 / s;
        q.p[0]   = ( m.getValue(j,k) - m.getValue(k,j) ) * s;
        q.p[j+1] = ( m.getValue(i,j) + m.getValue(j,i) ) * s;
        q.p[k+1] = ( m.getValue(i,k) + m.getValue(k,i) ) * s;
    }

    (*this) = q;
	
//Liu Ren changes here
/*	quater q;

    m_real tr, s;
    int    i, j, k;
    static int next[3] = { 1, 2, 0 };

    tr = m.getValue(0,0) + m.getValue(1,1) + m.getValue(2,2);
    if ( tr > 0.0 )
    {
        s = sqrt( tr + 1.0 );
        q.p[0] = ( s * 0.5 );
        s = 0.5 / s;
        q.p[1] = ( m.getValue(1,2) - m.getValue(1,2) ) * s;
        q.p[2] = ( m.getValue(0,2) - m.getValue(2,0) ) * s;
        q.p[3] = ( m.getValue(1,0) - m.getValue(0,1) ) * s;
    }
    else
    {
        i = 0;
        if ( m.getValue(1,1) > m.getValue(0,0) ) i = 1;
        if ( m.getValue(2,2) > m.getValue(i,i) ) i = 2;

        j = next[i];
        k = next[j];

        s = sqrt( (m.getValue(i,i)
					- (m.getValue(j,j) + m.getValue(k,k))) + 1.0 );
        q.p[i+1] = s * 0.5;
        s = 0.5 / s;
        q.p[0]   = ( m.getValue(k,j) - m.getValue(j,k) ) * s;
        q.p[j+1] = ( m.getValue(j,i) + m.getValue(i,j) ) * s;
        q.p[k+1] = ( m.getValue(k,i) + m.getValue(i,k) ) * s;
    }

    (*this) = q;
*/
}
matrix Quater2Matrix( quater const& q ){    matrix m;    m_real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;    s  = 2.0/len(q);    xs = q.x() * s;  ys = q.y() * s;  zs = q.z() * s;    wx = q.w() * xs; wy = q.w() * ys; wz = q.w() * zs;    xx = q.x() * xs; xy = q.x() * ys; xz = q.x() * zs;    yy = q.y() * ys; yz = q.y() * zs; zz = q.z() * zs;
	    m.p[0][0] = 1.0 - (yy + zz);    m.p[1][0] = xy - wz;    m.p[2][0] = xz + wy;    m.p[0][1] = xy + wz;    m.p[1][1] = 1.0 - (xx + zz);    m.p[2][1] = yz - wx;    m.p[0][2] = xz - wy;    m.p[1][2] = yz + wx;    m.p[2][2] = 1.0 - (xx + yy);
/*
	m.p[0][0] = 1.0 - (yy + zz);
    m.p[1][0] = xy + wz;
    m.p[2][0] = xz - wy;
    m.p[0][1] = xy - wz;
    m.p[1][1] = 1.0 - (xx + zz);
    m.p[2][1] = yz + wx;
    m.p[0][2] = xz + wy;
    m.p[1][2] = yz - wx;
    m.p[2][2] = 1.0 - (xx + yy);
*/    return m;}quater Matrix2Quater( matrix const& m ){   quater q;    m_real tr, s;    int    i, j, k;    static int next[3] = { 1, 2, 0 };    tr = m.getValue(0,0) + m.getValue(1,1) + m.getValue(2,2);    if ( tr > 0.0 )    {        s = sqrt( tr + 1.0 );        q.p[0] = ( s * 0.5 );        s = 0.5 / s;        q.p[1] = ( m.getValue(1,2) - m.getValue(2,1) ) * s;        q.p[2] = ( m.getValue(2,0) - m.getValue(0,2) ) * s;        q.p[3] = ( m.getValue(0,1) - m.getValue(1,0) ) * s;    }    else    {        i = 0;        if ( m.getValue(1,1) > m.getValue(0,0) ) i = 1;        if ( m.getValue(2,2) > m.getValue(i,i) ) i = 2;        j = next[i];        k = next[j];        s = sqrt( (m.getValue(i,i)					- (m.getValue(j,j) + m.getValue(k,k))) + 1.0 );        q.p[i+1] = s * 0.5;        s = 0.5 / s;        q.p[0]   = ( m.getValue(j,k) - m.getValue(k,j) ) * s;        q.p[j+1] = ( m.getValue(i,j) + m.getValue(j,i) ) * s;        q.p[k+1] = ( m.getValue(i,k) + m.getValue(k,i) ) * s;    }    return q;


	// Liu Ren changes here
/*	quater q;

    m_real tr, s;
    int    i, j, k;
    static int next[3] = { 1, 2, 0 };

    tr = m.getValue(0,0) + m.getValue(1,1) + m.getValue(2,2);
    if ( tr > 0.0 )
    {
        s = sqrt( tr + 1.0 );
        q.p[0] = ( s * 0.5 );
        s = 0.5 / s;
        q.p[1] = ( m.getValue(1,2) - m.getValue(1,2) ) * s;
        q.p[2] = ( m.getValue(0,2) - m.getValue(2,0) ) * s;
        q.p[3] = ( m.getValue(1,0) - m.getValue(0,1) ) * s;
    }
    else
    {
        i = 0;
        if ( m.getValue(1,1) > m.getValue(0,0) ) i = 1;
        if ( m.getValue(2,2) > m.getValue(i,i) ) i = 2;

        j = next[i];
        k = next[j];

        s = sqrt( (m.getValue(i,i)
					- (m.getValue(j,j) + m.getValue(k,k))) + 1.0 );
        q.p[i+1] = s * 0.5;
        s = 0.5 / s;
        q.p[0]   = ( m.getValue(k,j) - m.getValue(j,k) ) * s;
        q.p[j+1] = ( m.getValue(j,i) + m.getValue(i,j) ) * s;
        q.p[k+1] = ( m.getValue(k,i) + m.getValue(i,k) ) * s;
    }

    return q;
	*/}vector Quater2EulerAngle( quater const& q ){	return Matrix2EulerAngle( Quater2Matrix( q ) );}quater EulerAngle2Quater( vector const& v ){	return Matrix2Quater( EulerAngle2Matrix( v ) );}m_real len( quater const& v ){    return sqrt( v.p[0]*v.p[0] + v.p[1]*v.p[1] + v.p[2]*v.p[2] + v.p[3]*v.p[3] );}m_realquater::length() const{    return sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] + p[3]*p[3] );}quaterquater::normalize() const{	return (*this)/this->length();}ostream& operator<<( ostream& os, quater const& a ){    os << "( " << a.p[0] << " , " << a.p[1] << " , " << a.p[2] << " , " << a.p[3] << " )";    return os;}istream& operator>>( istream& is, quater& a ){
	static char	buf[256];	//is >> "(" >> a.p[0] >> "," >> a.p[1] >> "," >> a.p[2] >> "," >> a.p[3] >> ")";
	is >> buf >> a.p[0] >> buf >> a.p[1] >> buf >> a.p[2] >> buf >> a.p[3] >> buf;    return is;}quater exp(vector const& w){    m_real theta = sqrt(w % w);    m_real sc;    if(theta < eps) sc = 1;    else sc = sin(theta) / theta;    vector v = sc * w;    return quater(cos(theta), v.x(), v.y(), v.z());}quater pow(vector const& w, m_real a){    return exp(a * w);}vector ln(quater const& q){    m_real sc = sqrt(q.p[1] * q.p[1] + q.p[2] * q.p[2] + q.p[3] * q.p[3]);    m_real theta = atan2(sc, q.p[0]);    if(sc > eps)        sc = theta / sc;    else  sc = 1.0 ;    return vector(sc * q.p[1], sc * q.p[2], sc * q.p[3]);}position rotate(quater const& a, position const& v){    quater c = a * quater(0, v.x(), v.y(), v.z()) * inverse(a);    return position(c.x(), c.y(), c.z());}vector rotate(quater const& a, vector const& v){    quater c = a * quater(0, v.x(), v.y(), v.z()) * inverse(a);    return vector(c.x(), c.y(), c.z());}unit_vector rotate(quater const& a, unit_vector const& v){    quater c = a * quater(0, v.x(), v.y(), v.z()) * inverse(a);    return unit_vector(c.x(), c.y(), c.z());}quaterslerp( quater const& a, quater const& b, m_real t ){

	quater aa, bb;
	
    m_real c = a % b;
    
	if(c>=0){

		aa = a;
		bb = b;

	}else{

		aa = a;
		bb = -b;
		c = -c;
	}


	m_real theta = acos( c );
	m_real sinom = sin( theta );

	if(sinom>eps){
	return ((aa*sin((1-t)*theta) + bb*sin(t*theta))/sinom).normalize();
	}else{

		return (aa*(1-t) + bb*t).normalize();
		//return aa.normalize();
	}
/*		m_real c = a % b;	if ( 1.0+c > EPS )	{		if ( 1.0-c > EPS )		{			m_real theta = acos( c );			m_real sinom = sin( theta );			return ( a*sin((1-t)*theta) + b*sin(t*theta) ) / sinom;		}		else			return (a*(1-t) + b*t).normalize();	}	else	return a*sin((0.5-t)*M_PI) + b*sin(t*M_PI);*/
 }quaterinterpolate( m_real t, quater const& a, quater const& b ){	return slerp( a, b, t );}


quater
doublequater(quater const& a, quater const& b)
{

	//a and b should be unit quaternion
	quater result;
	result = 2.0*(a%b)*b-a;

//	result.normalize();
	return result;
}


quater
doublequaterk(quater const& a, quater const& b, m_real k)
{

	//a and b should be unit quaternion
	quater result;
	result =(1/k)*2.0*(a%b)*b-a;

	result.normalize();
	return result;
}

quater
decasteljau(quater const& q1, quater const& q2,quater const& q3, quater const& q4,m_real t){
// simplified version
//	quater pp = slerp(slerp(q1,q4,t),slerp(q2,q3,t),2*t*(1-t));

	quater p1,p2,p3,p12,p23,p;
	
	p1 = slerp(q1,q2,t);
	p2 = slerp(q2,q3,t);
	p3 = slerp(q3,q4,t);

	p12 = slerp(p1,p2,t);
	p23 = slerp(p2,p3,t);

	p= slerp(p12,p23,t);

	return p;
}

quater 
bisect(quater const& a, quater const& b)
{
	quater result;
	result = a+b;

	return result.normalize();
}
quater
closetofirst(quater const& a, quater const & b)
{
	m_real t;
	t = a%b;
	if (t>=0) return b;
	else return -b;

}
m_realdistance( quater const& a, quater const& b ){	return MIN( ln( a.inverse()* b).length(),				ln( a.inverse()*-b).length() );}vectordifference( quater const& a, quater const& b ){	return ln( b.inverse() * a );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -