定义三维点
namespace Data{
template<typename _value_type_>
class _V3{
public:
_V3(){}
_V3(const _value_type_& _x_,
const _value_type_& _y_,
const _value_type_& _z_):
_x(_x_),_y(_y_),_z(_z_){}
~_V3(){}
//
_value_type_& x(){return _x;}
_value_type_& y(){return _y;}
_value_type_& z(){return _z;}
_value_type_& w(){return _w;}
//重载运算符
bool operator !=(const _V3& that){
if(this->_x!=that._x || this->_y!=that._y || this->_z!=that._z) return true;
return false;
}
_V3 operator -(const _V3& that){
_V3 temp;
temp._x=this->_x-=that._x;
temp._y=this->_y-=that._y;
temp._z=this->_z-=that._z;
return temp;
}
//向量积(叉积)
_V3 operator ^(const _V3& that){
//叉积推导
/*
i=1 ,j=1 ,k=1,
x1 ,y1 ,z1,
x2 ,y2 ,z2,
i*y1*z2+j*z1*x2+k*x1*y2-i*z1*y2-j*x1*z2-k*y1*x2
=>i(y1*z2-z1*y2),j(z1*x2-x1*z2),k(x1*y2-y1*x2)
*/
_V3 temp;
temp.x()=this->_y*that._z-this->_x*that._y;
temp.y()=this->_z*that._x-this->_x*that._z;
temp.z()=this->_x*that._y-this->_y*that._x;
temp.w()=1;
return temp;
}
//数量积
_value_type_ operator *(const _V3& that){
return (this->_x*that._x+this->_y*that._y+this->_z*that._z);
}
_V3 operator *(_value_type_ v){
_V3 temp;
temp._x=this->_x*v;
temp._y=this->_y*v;
temp._z=this->_z*v;
return temp;
}
_V3& operator =(const _V3& that){
this->_x=that._x;
this->_y=that._y;
this->_z=that._z;
return *this;
}
_V3& operator +=(const _V3& that){
this->_x+=that._x;
this->_y+=that._y;
this->_z+=that._z;
return *this;
}
_V3& operator *=(const _value_type_ v){
this->_x*=v;
this->_y*=v;
this->_z*=v;
return *this;
}
//单位化
_value_type_ normalize(){
auto len=sqrt(this->_x*this->_x+this->_y*this->_y+this->_z*this->_z);
if(len>0.0f){
float inv=1.0/len;
this->_x*=inv;
this->_y*=inv;
this->_z*=inv;
}
return len;
}
_value_type_& operator [](int i){
switch(i%3){
case 0:return _x;
case 1:return _y;
case 2:return _z;
}
}
private:
_value_type_ _x;
_value_type_ _y;
_value_type_ _z;
_value_type_ _w;
};
};
定义旋转矩阵
namespace Data{
//定义旋转矩阵
template<typename _value_type_>
class RotatoMatrix{
public:
RotatoMatrix(){}
~RotatoMatrix(){}
//设置参数
void setC(const V3<_value_type_>& C){_c=C;}
void setN(const V3<_value_type_>& N){_n=N;}
void setN2(const V3<_value_type_>& N2){_n2=N;}
//获取参数
void getC(){return _c;}
void getN(){return _n;}
void getN2(){return _n2;}
//
_value_type_& r(){return _r;}
//
_V3<_value_type_> smartCalcN2(){
//已知轴向,计算任意一个垂直向量,需要取非零向量为参考向量。
_V3<_value_type_> x1(1.0,0.0,0.0);
_V3<_value_type_> y1(0.0,1.0,0.0);
_V3<_value_type_> z1(0.0,0.0,1.0);
if(_n!=x1) this->_n2=this->_n^x1;
else if(_n!=y1) this->n2=this->n^y1;
else this->_n2=this->_n^z1;
//
this->_n2.normalize();
return this->_n2;
}
//
std::vector<_V3<_value_type_>> geRcs(float radf,float rade,float rinterver){
auto n3=_n2*r;
return getRcs(n3,radf,rade,rinterver);
}
std::vector<_V3<_value_type_>> getRcs(_V3<_value_type_> begin,float radf,float rade,float rinterver){
//已知轴向
//中心点
/*旋转矩阵
n1²(1-cosθ)+cosθ ,n1n2(1-cosθ)-n3sinθ ,n1n3(1-cosθ)+n2sinθ ,0
n1n2(1-cosθ)+n3sinθ ,n2²(1-cosθ)+cosθ ,n2n3(1-cosθ)-n1sinθ ,0
n1n3(1-cosθ)-n2sinθ ,n2n3(1-cosθ)+cosθ ,n3²(1-cosθ)+cosθ ,0
0 ,0 ,0 ,1
*/
_value_type_ n1=_n[0];
_value_type_ n2=_n[1];
_value_type_ n3=_n[2];
std::vector<_V3<_value_type_>> testline;
for(float ri=radf;ri<=rade;ri++){
float m11=n1*n1*(1-cos(ri))+cos(ri) ,m12=n1*n2*(1-cos(ri))-n3*sin(ri) ,m13=n1*n3*(1-cos(ri))+n2*sin(ri) ,m14=0;
float m21=n1*n2*(1-cos(ri))+n3*sin(ri) ,m22=n2*n2*(1-cos(ri))+cos(ri) ,m23=n2*n3*(1-cos(ri))-n1*sin(ri) ,m24=0;
float m31=n1*n3*(1-cos(ri))-n2*sin(ri) ,m32=n2*n3*(1-cos(ri))+cos(ri) ,m33=n3*n3*(1-cos(ri))+cos(ri) ,m34=0;
float m41=_c[0] ,m42=_c[1] ,m43=_c[2] ,m44=1;
//
float x=begin.x(),y=begin.y(),z=begin.z(),w=1;
_V3<_value_type_> tempPi;
tempPi.x()=(x*m11+y*m21+z*m31+w*m41);
tempPi.y()=(x*m12+y*m22+z*m32+w*m42);
tempPi.z()=(x*m13+y*m23+z*m33+w*m43);
tempPi.w()=(x*m14+y*m24+z*m34+w*m44);
testline.push_back(tempPi);
}
return testline;
}
private:
_V3<_value_type_> _c;
_V3<_value_type_> _n;
_V3<_value_type_> _n2;
_value_type_ r;
};
};
测试
int main(){
#define MPI 3.14159265358979323846
using V3f=Data::_V3<float>;
std::vector<V3f> testline;
testline.push_back(V3f(10,0,0));
testline.push_back(V3f(20,10,0));
testline.push_back(V3f(30,0,0));
testline.push_back(V3f(40,10,0));
testline.push_back(V3f(50,0,0));
using RotateMatrixF=Data::RotatoMatrix<float>;
//
RotateMatrixF RM;
RM.setC(testline.front());
RM.setN((testline[0]-testline[1]).normalize());
RM.r()=1;
RM.smartCalcN2();
auto lines=RM.getRcs(0,MPI*2,MPI*2/32.0);
return 0;
#undef MPI
}