2 向量、矩阵及四元数
数据是计算机图形学研究的基础,常用的数据工具主要包括向量、矩阵及四元数等,这些数据适用于不同的情况,各有优缺点。。
2.1向量
osg定义了大量的类,用于保存向量数据,如顶点、法向、颜色和纹理坐标等。osg::Vec3是一个三维浮点数组。osg::Vec4用于保存颜色数据。osg::Vec2可用于保存2D纹理坐标。
基本的向量类如下:
二维向量 | 三维向量 | 四维向量 |
---|---|---|
osg::Vec2b | osg::Vec3b | osg::Vec4b |
osg::Vec2d | osg::Vec3d | osg::Vec4d |
osg::Vec2f | osg::Vec3f | osg::Vec4f |
osg::Vec2s | osg::Vec3s | osg::Vec4s |
向量运算如下:
value_type length() const | // 长度计算 |
---|---|
value_type length2() const | // 长度平方计算 |
value_type normalize() const | // 单位化 |
const Vec2f operator+(const Vec2f& rhs)const | // 加法(其他四则远算类似) |
const Vec2f operator+=(const Vec2f& rhs)const | |
bool operator==(const Vec2f&v)const | 比较判断 |
bool operator!=(const Vec2f&v)const | 比较判断 |
bool operator<(const Vec2f&v)const | 比较判断 |
2.2矩阵
矩阵是3D数学的重要基础。在OSG中定义了一些相关的类用来保存矩阵数据,如物体的方位、摄像机方位和位置等信息。
*osg::Matrix2* | |
---|---|
*osg::Matrix3* | |
*osg::Matrixd* | |
*osg::Matrixf* | |
*void operator*=(const Matrixf&other)* | 乘法 |
*Matrixf operator*(const Matrixf&m)const* | |
*bool invert(const Matrixf &rhs)* | 逆矩阵 |
*void makeScale(const Vec3f&)* | 缩放 |
*void makeTranlate(const Vec3f&)* | 平移 |
*void makeRotate(const Vec3f&from,const Vec3f &to)* | 旋转 |
*bool operator<(const Matrixf &m)const* | 比较判断 |
*bool operator==(const Matrixf &m)const* | |
*bool operator!=(const Matrixf &m)const* |
10.2.3四元数(osg::Quat)
一个四元数由一个标量和一个矢量组成,但这个矢量不是我们通常所讨论的三维空间,而是四维空间,可以表示为[w,v]或者[w,(x,y,z)],其中w是标量,v是矢量。
W
=
c
o
s
(
θ
/
2
)
W=cos(θ/2)
W=cos(θ/2)
X = a x ∗ s i n ( θ / 2 ) X=ax*sin(θ/2) X=ax∗sin(θ/2)
Y = a y ∗ s i n ( θ / 2 ) Y=ay*sin(θ/2) Y=ay∗sin(θ/2)
Z = a z ∗ s i n ( θ / 2 ) Z=az*sin(θ/2) Z=az∗sin(θ/2)
其中, 表示轴的矢量, 表示绕此轴的旋转角堵。不过,需要注意的是, 是极坐标下的角度。当然,用轴角来描述也是可以的,只是上面的参数不能简单理解为坐标轴和角度之间的值。在使用四元数时,也可以写成轴角表示方式。
四元数存在于3D数学中有一个重要原因,其有一种slerp插值运算。slerp插值运算是一种空间的平滑的球面线性插值,没有其他方法可以提供如此的平滑插值。插值的基本思想是基于四维空间极坐标轴弧线差值。四元数的平滑插值在场景交互过程中发挥着重要的作用,提供了平滑的渲染过程,如场景漫游等。
*void makeRotate(value_type angle,value_type x,y,z)* | 旋转 |
---|---|
*value_type length()const* | 长度计算 |
*value_type length2()cosnt* | |
*const Quat operator+(const Quat&ths)const* | 加法 |
*void operator*=(const Matrixf&other)* | 乘法 |
*Quat& operator+=(const Quat&rhs)* | |
*…* | |
*void slerp(value_type t,const Quat& from,const Quat&to)* | 插值 |
*Vec3f operator*(const Vec3f&v)const* | 与向量相乘 |
*Vec3d operator*(const Vec3d&v)const* |
平滑的插值只能用四元数来完成,如果想用其它的方式,需要先转换为四元数,待插值完毕再转换成原格式。
10.2.4矩阵与四元数之间的转换
矩阵和四元数在表达方位上各有优势,在不同的情况下,可以选择使用矩阵、四元数或两者的综合。矩阵能够在坐标系之间转换向量,而四元数则不能四元数能够提供平滑的线性插值,而矩阵差值结果是非常粗糙的。因此,适当的时侯矩阵和四元数的转换是非常有必要的。
W
=
c
o
s
(
θ
/
2
)
W=cos(θ/2)
W=cos(θ/2)
X = a x ∗ s i n ( θ / 2 ) X=ax*sin(θ/2) X=ax∗sin(θ/2)
Y = a y ∗ s i n ( θ / 2 ) Y=ay*sin(θ/2) Y=ay∗sin(θ/2)
Z = a z ∗ s i n ( θ / 2 ) Z=az*sin(θ/2) Z=az∗sin(θ/2)
一般四元数转换为矩阵的公式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HymCWtrF-1647347932984)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220315203459574.png)]
规范化四元数转换为矩阵的公式如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W1f8qYM4-1647347932986)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\image-20220315203515090.png)]
代码清单:
// 四元数转换为矩阵
*void setRotate(const Quat&q);*
// 矩阵转换为四元素
*Quat getRotate()const;*
)]
代码清单:
// 四元数转换为矩阵
*void setRotate(const Quat&q);*
// 矩阵转换为四元素
*Quat getRotate()const;*