首页 > 其他分享 >计算机图形:三维几何变换

计算机图形:三维几何变换

时间:2023-10-08 15:47:34浏览次数:36  
标签:begin end cos 三维 旋转 几何变换 bmatrix theta 图形

目录

三维几何变换,是在二维基础上扩展z坐标得到。三维位置齐次坐标表示为4元列向量。任意三维变换序列,可通过合并相应变换矩阵,而得到一个矩阵来表示。

三维平移

点的平移

任意点P=(x,y,z)按向量\((t_x,t_y,t_z)\)平移后,得到新位置\(P'=(x',y',z')\),有:

\[\tag{1} x'=x+t_x, y'=y+t_y,z'=z+t_z \]

用4元列向量齐次坐标表示平移变换,变换操作T是4x4矩阵:

\[\tag{2} \begin{bmatrix} x' \\ y' \\ z' \\ 1 \end{bmatrix} =\begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} \]

简洁形式:

\[\tag{3} P'=T\cdot P \]

对象的平移

对象的平移通过定义该对象的所有点的平移来实现。如果对象用一组多边形表示,这可将各个表面的顶点进行平移。

三维旋转

对象可以绕任意轴旋转,但绕平行于坐标轴的旋转更容易处理,故先讨论。

正旋转方向:视线沿着坐标轴负向观察原点,绕坐标轴逆时针旋转定义为正向旋转。

三维坐标轴旋转

  • 绕z轴旋转

绕z轴的二维旋转,可看做特殊三维旋转:

\[\tag{4} \begin{aligned} x' &= x\cos \theta - y\sin \theta \\ y' &= x\sin \theta + y\cos \theta \\ z' &= z \end{aligned} \]

变换矩阵:

\[R_z(\theta)=\begin{bmatrix} \cos\theta & -\sin\theta & 0 & 0\\ \sin\theta & \cos\theta & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

坐标变换写成齐次坐标的矩阵形式:

\[\tag{5} \begin{bmatrix} x' \\ y' \\ z' \\ 1 \end{bmatrix} =\begin{bmatrix} \cos \theta & -\sin \theta & 0 & 0 \\ \sin \theta & \cos \theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} \]

其中,\(\theta\)表示绕z轴旋转角度。

简洁形式:

\[\tag{6} P'=R_z(\theta)\cdot P \]

  • 如果是绕x轴、y轴旋转呢?

可以基于式(4),用y替代x、z替代y、x替代z。循环替换顺序:

\[\tag{7} x->y->z->x \]

1)绕x轴旋转(x-axis rotation)变换公式:

\[\tag{8} \begin{aligned} y'&=y\cos\theta - z\sin\theta \\ z'&=y\sin\theta + z\cos\theta \\ x'&=x \end{aligned} \]

变换矩阵:

\[R_x(\theta)=\begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & \cos\theta & -\sin\theta & 0\\ 0 & \sin\theta & -\cos\theta & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

2)绕y轴旋转(y-axis rotation)变换公式:

\[\tag{9} \begin{aligned} z'&=z\cos\theta-x\sin\theta \\ x'&=z\sin\theta+x\cos\theta \\ y'&=y \end{aligned} \]

变换矩阵:

\[R_y(\theta)=\begin{bmatrix} \cos\theta & 0 & \sin\theta & 0\\ 0 & 1 & 0 & 0\\ -\sin\theta & 0 & \cos\theta & 0\\ 0 & 0 & 0 &1 \end{bmatrix} \]

  • 旋转矩阵的逆

可以用\(-\theta\)替换旋转角\(\theta\),得到逆旋转矩阵为原旋转的逆。根据式(5),

\[\tag{10} \begin{aligned} R_z(-\theta)&=\begin{bmatrix} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \\&= R_z(\theta)^T \end{aligned} \]

当然,求逆对于绕x轴、y轴旋转的变换矩阵同样成立。

一般三维旋转

绕任意轴的旋转,可用平移+坐标轴旋转的复合得到。

绕平行于坐标轴的轴旋转

平移+坐标轴旋转的复合=>变换矩阵。步骤:
1)平移对象,使其旋转轴与平行于该轴的坐标轴重合;
2)绕该坐标轴完成指定的旋转;
3)平移对象,将其旋转轴移回原来的位置。

对象上任意点P可通过复合变换得到新位置P'。例如,绕平行于x轴的轴旋转:

\[\tag{11} \begin{aligned} P'&=R(\theta)\cdot P \\ &=T^{-1}\cdot R_x(\theta)\cdot T\cdot P \end{aligned} \]

其中,\(R(\theta)\)为旋转变换的复合矩阵,\(R_x(\theta)\)为绕x轴旋转的变换矩阵。

绕任意轴旋转

多一步,需先将旋转轴旋转到与坐标轴重合。步骤:
1)平移对象,使旋转轴通过坐标原点;
2)旋转对象,使旋转轴与某一坐标轴重合;
3)绕该坐标轴旋转指定角度;
4)逆旋转,回到原来的方向;
5)逆平移,回到原来的位置。

假设旋转轴由2个点P1、P2确定,\(P_1(x_1,y_1,z_1),P_2(x_2,y_2,z_2)\)。

  • 如果沿着P2到P1的方向观察,旋转方向为逆时针,则轴向量V可定义为:

\[\tag{12} \begin{aligned} V&=P_2-P_1 \\ &=(x_2-x_1,y_2-y_1,z_2-z_1) \end{aligned} \]

旋转轴的单位向量u:

\[u={V\over |V|}=(a,b,c) \]

其中,分量a、b、c为旋转轴的方向余弦:

\[\tag{13} a={x_2-x_1\over |V|}, b={y_2-y_1\over |V|}, c={z_2-z_1\over |V|} \]

  • 如果以相反方向旋转(顺时针),则要将轴向量V和单位向量u取反。

tips:何为方向余弦?
假设旋转轴单位向量u与x、y、z轴夹角分别为\(\alpha, \beta, \gamma\),而u模(长度)为1(\(|u|=1\)),则向量u可表示为:

\[\begin{aligned} u&=(1*\cos\alpha, 1*\cos\beta, 1*\cos\gamma) \\ &=(\cos\alpha, \cos\beta, \cos\gamma) \end{aligned} \]

因此,u的分量a、b、c称为方向余弦。

下面对每一步分析:
1)平移对象,建立使旋转轴通过原点的平移变换矩阵。由于需要从P2往P1看的逆时针旋转,因此将P1(而非P2)移动到原点。变换矩阵:

\[\tag{14} T=\begin{bmatrix} 1 & 0 & 0 & -x_1 \\ 0 & 1 & 0 & -y_1 \\ 0 & 0 & 1 & -z_1 \\ 0 & 0 & 0 & 1 \end{bmatrix} \]

2)将旋转轴旋转至与z轴重合。2次旋转:绕x轴旋转,绕y轴旋转。绕x轴旋转,将轴向量u变换到xz平面;绕y轴旋转,将u变换到z轴上。

(1)绕x轴旋转至与z轴重合,得到变换矩阵.
设u在yz平面投影为向量\(u'=(0,b,c)\),则旋转角\(\alpha\)(u'与z轴夹角)对应余弦:

\[\tag{15} \cos\alpha={u'\cdot u_z\over |u'||u_z|}={c\over d} \]

其中,\(u_z\)为z轴上单位向量,d为u'的模。

\[\tag{16} \begin{aligned} d&=\sqrt{b^2+c^2} \\ u_z&=(0,0,1) \end{aligned} \]

\(u'(0,b,c)\)及其在z轴投影构成的直角三角形如下:
b48de02d98061f443a891db4f1952718.png
注意:u'在z轴投影不是\(u_z\),也不是单位向量。

将向量u分2步旋转到z轴的示意图(注意逆时针旋转):
b54b63dccb81ce517d36917830a0decc.png

等价于将u'(u在yz平面投影)绕x轴旋转α角:
34db4fb39213142d3264ed95420546d4.png

绕x轴旋转α角,可以将u旋转到xz平面。对应旋转矩阵:

\[\tag{17} R_x(\alpha)=\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\alpha & -\sin\alpha & 0 \\ 0 & \sin\alpha & \cos\alpha & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \]

而\(\sin\alpha\)可由叉积得到:

\[\begin{aligned} u'\times u_z&=u_x|u'||u_z|\sin\alpha, 叉积方向符合右手定则, 这里u_x(1,0,0)代表方向 \\ &=u_x|u'|\cdot 1\cdot \sin\alpha \\ &= u_x\cdot b \end{aligned} \]

记\(|u'|=d\),有

\[u_x=(1,0,0)\implies |u_x|=1 \\ \therefore d\sin\alpha=b, \sin\alpha={b\over d} \tag{18} \]

现已求得\(\cos\alpha, \sin\alpha\),代入(17),可得:

\[\tag{19} R_x(\alpha)=\begin{bmatrix} 1 & 0 & 0 & 0\\ 0 & {c\over d} & -{b\over d} & 0\\ 0 & {b\over d} & {c\over d} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

(2)再绕y轴旋转,将xz平面上单位向量旋转至与z轴正方向重合,得到变换矩阵。
单位向量u绕x轴逆时针旋转α角得到位于xz平面的单位向量u'',再绕y轴逆时针旋转β角,得到位于z轴的单位向量\(u_z(0,0,1)\)。
u''是u(a,b,c)绕x轴旋转得到,因此x分量不变;因为u''位于xz平面,所以y分量为0。设u''=(a,0,z),有
\( \because u''由u旋转得到\\ \therefore 长度不变, |u''|=|u|=\sqrt {a^2+b^2+c^2} = 1\\ \therefore a^2+b^2+c^2=1\\ \because d=\sqrt {b^2+c^2}>0\\ \therefore a^2+d^2=1\\ 而根据u''坐标, |u''|=\sqrt {a^2+z^2}=1=\sqrt {a^2+d^2}\\ \therefore |z|=d \)
这里取z=d。

思考问题:为什么z=d,而不是z=-d?
Donald Hearn注,蔡士杰译《计算机图形学(第4版)》给出的解释是:因为u'旋转到z轴上,故u''的z分量为d。这里不以为意,因为u'是u在yz平面投影,与u''并没有直接联系。而且,d为u'的模(正直),但u旋转后得到u''的z分量完全可能为负值。

因为旋转变换矩阵与旋转角余弦、正弦值有关,因此通过点积、叉积来求。
点积求\(\cos\beta\):

\[\tag{20} \cos\beta={u''\cdot u_z\over |u''||u_z|}={(a,0,d)\cdot (0,0,1)\over |1||1|}={d\over 1}=d \]

叉积求\(\sin\beta\):

\[\begin{aligned} u''\times u_z&=u_y|u''||u_z|\sin\beta \\ &=u_y\cdot (-a) \end{aligned} \\ \implies \sin\beta=-a \tag{21} \]

因此,u''绕y轴的旋转变换矩阵:

\[\tag{22} \begin{aligned} R_y(\beta)&=\begin{bmatrix} \cos\beta & 0 & \sin\beta & 0\\ 0 & 1 & 0 & 0\\ -\sin\beta & 0 & \cos\beta & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}\\ &=\begin{bmatrix} d & 0 & -a & 0\\ 0 & 1 & 0 & 0\\ a & 0 & d & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \end{aligned} \]

3)绕旋转轴旋转
经过平移、绕x轴旋转、绕y轴旋转后,可以将旋转轴对齐到z轴正方向。此时,绕旋转轴旋转\(\theta\),可以直接用关于z轴旋转的矩阵变换:

\[\tag{23} R_z(\theta)=\begin{bmatrix} \cos\theta & -\sin\theta & 0 & 0\\ \sin\theta & \cos\theta & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

4)5)逆旋转、逆平移回原来的位置
对任意轴的旋转,变换矩阵可以表示成:

\[\tag{24} R(\theta)=T^{-1}\cdot R_x^{-1}(\alpha)\cdot R_y^{-1}(\beta)\cdot R_z(\theta)\cdot R_y(\beta)\cdot R_x(\alpha)\cdot T \]

三维缩放

相当于原点的缩放

相对于原点的三维缩放变换:

\[\tag{25} \begin{bmatrix} x' \\ y' \\ z' \\ 1 \end{bmatrix} =\begin{bmatrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & s_z & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} \]

其中,缩放参数\(s_x, s_y, s_z\)为指定的任意正值。原坐标与变换后坐标关系为:

\[\tag{26} \begin{aligned} x'&=x\cdot s_x\\ y'&=y\cdot s_y\\ z'&=z\cdot s_z \end{aligned} \]

简写:

\[\tag{27} P'=S\cdot P \]

缩放系数>1 ,代表沿该方向放大物体;缩放系数<1,代表沿该方向缩小物体;缩放系数\(s_x=s_y=s_z=1\),代表保持原来的形状。缩放系数必须>0。

相对于任意点的缩放

步骤:

  1. 平移指定点到原点;
  2. 使用相对于原点缩放对象;
  3. 将指定点平移回原位置。

相当于任意点\((x_f,y_f,z_f)\)的缩放变换矩阵:

\[\tag{28} \begin{aligned} T(x_f,y_f,z_f)\cdot S(s_x,s_y,s_z)\cdot T(-x_f, -y_f, -z_f) &= \begin{bmatrix} 1 & 0 & 0 & x_f\\ 0 & 1 & 0 & y_f\\ 0 & 0 & 1 & z_f\\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} s_x & 0 & 0 & 0\\ 0 & s_y & 0 & 0\\ 0 & 0 & s_z & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} 1 & 0 & 0 & -x_f\\ 0 & 1 & 0 & -y_f\\ 0 & 0 & 1 & -z_f\\ 0 & 0 & 0 & 1 \end{bmatrix}\\ &=\begin{bmatrix} s_x & 0 & 0 & (1-s_x)x_f\\ 0 & s_y & 0 & (1-s_y)y_f\\ 0 & 0 & s_z & (1-s_z)z_f\\ 0 & 0 & 0 & 1 \end{bmatrix} \end{aligned} \]

三维复合变换

类似于二维复合变换,可以将三维变换序列中各个变换矩阵相乘,得到三维复合变换。最右边的矩阵是最先作用于对象的,最左边是最后一个。

OpenGL矩阵栈

使用glMatrixMode选择建模观察复合变换矩阵,用于以后的OpenGL变换调用。
对支持的4种模式(建模观察、投影、纹理、颜色)的每一种,OpenGL维护一个矩阵栈。开始时,每个栈仅包含单位矩阵;处理场景时,栈顶的矩阵称为该模式的“当前矩阵”。指定观察和几何变换后,建模观察栈(modeview matrix stack)顶是一个4x4复合矩阵,应用于场景的观察变换和各种几何变换。
因为可能要创建多个视图和变换序列,然后分别保存复合矩阵,所以OpenGL提供深度至少为32的建模观察栈。

  • 查询特定实现中建模观察栈的有效位置数
glGetIntegerv(GL_MAX_MODEVIEW_STACK_DEPTH, stackSize);

将一个整数值返回给数组stackSize。另外3个矩阵模式(投影、纹理、颜色)的栈深度至少为2,可用下列符号常量确定:GL_MAX_PROJECTION_STACK_DEPTH, GL_MAX_TEXTURE_STACK_DEPTH, GL_MAX_COLOR_STACK_DEPTH。

  • 查询栈中当前有多少矩阵
glGetIntegerv(GL_MODEVIEW_STACK_DEPTH, numMats);

如果在栈处理前调用该函数,则返回1,此时仅包含单位阵。类似的复合常量也可用来确定其他三个栈中当前矩阵数

  • 操作栈

复制栈顶的当前矩阵,兵存入第二个栈位置

glPushMatrix();

破坏栈顶矩阵,使第二个矩阵称为当前矩阵。如果“弹出”栈顶,栈内至少要2个矩阵;否则出错。

glPopMatrix();

标签:begin,end,cos,三维,旋转,几何变换,bmatrix,theta,图形
From: https://www.cnblogs.com/fortunely/p/17749241.html

相关文章

  • 研发三维GIS系统笔记/实现wgs84投影-001
    1.工作内容,改造引擎,支持wgs84投影改造原因:目前投影是墨卡托投影(与GoogleMap一致)目前的GIS系统是二维的采用这个坐标系是没有问题的但不支持wgs84瓦片数据以及高程数据,工作中很多数据是wgs84格式的,尤其很多三维GIS都是采用wgs84投影wgs84与mercator从数据上......
  • 三维模型3DTile格式轻量化的纹理压缩和质量关系分析
    三维模型3DTile格式轻量化的纹理压缩和质量关系分析 在三维模型的3DTile格式轻量化处理中,纹理压缩是一个重要环节。但是,纹理压缩和模型质量之间存在明显的关系需要权衡。以下是纹理压缩和模型质量关系的详细分析:1、压缩率与纹理质量:一般来说,高度压缩的纹理可以大大减小文件大......
  • 【实用】登录图形认证 图形码 验证码 中文图形验证码 动态图形验证码 图片验证码 验证
    后端测试: 主要code:https://www.cnblogs.com/liuguiqing/p/17722366.html ......
  • numpy 多维数据的理解(三维数据,更多维度)
    numpy 多维数据的理解(三维数据,更多维度)In[22]:a=np.array([[11,12,13,14,15],...:[16,17,18,19,20],...:[21,22,23,24,25],...:[26,27,28,29,30],...:[31,32,33,34,......
  • 三维模型3DTile格式轻量化的数据压缩与性能平衡关系分析
    三维模型3DTile格式轻量化的数据压缩与性能平衡关系分析 对于三维模型的3DTile格式轻量化处理,数据压缩和性能之间的平衡关系是一个重要的考虑因素。以下是这两者关系的详细分析:1、数据压缩与加载速度:显然,更高级别的压缩可以创造更小的文件大小,从而加快从服务器到客户端的传输......
  • 构造Vulkan图形管线:VkGraphicsPipeline
     创建Pipeline构造信息:它包括:基本构造信息VkStructureType构建Pipeline额外需要的结构:constvoid*pNext构建Pipeline时指定的Flags:VkPipelineCreateFlags多个ShaderStage信息:VkPipelineShaderStageCreateInfo*(数组)......
  • 医学影像归档与通讯系统(PACS)系统源码 PACS三维图像处理
    医学影像归档与通讯系统(PACS)系统源码 PACS三维图像处理医学影像归档与通讯系统(PACS)系统,是一套适用于从单一影像设备到放射科室、到全院级别等各种应用规模的医学影像归档与通讯系统。PACS集患者登记、图像采集、存档与调阅、报告与打印、查询、统计等功能为一体,有效地实现了对海量......
  • 2.几何图形
    2.1绘制直线......
  • 图形学 Cellular Noise
    前言本篇重点如何实现CellularNoise定义CellularNoise基于Voronoi图生成,其外观就像是一个个紧挨着的细胞,因而得名CellularNoise。而Voronoi图的定义是由一组连续多边形组成,多边形的形成由其内部的控制点来控制,按照最邻近原则划分平面,即每个多边形都代表平面上离其内部控制......
  • 视频融合/监控汇聚平台EasyCVR为三维全景拼接赋能
    视频融合技术是虚拟现实技术的一个分支,它是虚拟现实发展的一个阶段。三维视频融合技术通过匹配和融合一个或多个由摄像机图像序列视频和相关的三维虚拟场景,生成一个关于该场景的动态虚拟场景或模型,实现虚拟场景与实时视频的融合,即虚实融合。虚实融合指的是将视频画面精确地融合显......