怎么建设外贸网站,域名停域免费观看软件,班级优化大师网页版登录,做网站素材在哪里找文章目录QT OpenGL变换向量的运算矩阵矩阵与向量相乘代码实现QT OpenGL
本篇完整工程见gitee:QTOpenGL 对应点的tag#xff0c;由turbolove提供技术支持#xff0c;您可以关注博主或者私信博主。
变换
我们需要改变物体的位置
现有解决办法#xff08;每一帧#xff0c…
文章目录QT OpenGL变换向量的运算矩阵矩阵与向量相乘代码实现QT OpenGL
本篇完整工程见gitee:QTOpenGL 对应点的tag由turbolove提供技术支持您可以关注博主或者私信博主。
变换
我们需要改变物体的位置
现有解决办法每一帧改变顶点位置所有顶点
每个顶点使用向量表示使用矩阵表示对应顶点的操作。
向量的运算
向量是有方向和大小的量 a⃗(xyz)\vec{a} \left(\begin{matrix} x \\ y \\z \end{matrix}\right) axyz 向量与标量运算 标量(Scalar)只是一个数字或者说是仅有一个分量的向量。当把一个向量加/减/乘/除一个标量我们可以简单的把向量的每个分量分别进行该运算。对于加法来说会像这样: (123)x(1x2x3x)\left(\begin{matrix}1 \\ 2 \\3 \end{matrix}\right) x \left(\begin{matrix}1x \\ 2x \\3x \end{matrix}\right) 123x1x2x3x 其中的可以是-·或÷其中·是乘号。注意和÷运算时不能颠倒标量-/÷向量因为颠倒的运算是没有定义的。
向量取反 −a⃗−(xyz)(−x−y−z)-\vec{a} -\left(\begin{matrix}x \\ y \\z \end{matrix}\right) \left(\begin{matrix}-x \\ -y \\-z \end{matrix}\right) −a−xyz−x−y−z 向量加减 a⃗(123),b⃗(123),a⃗b⃗(112233)(246)\vec{a} \left(\begin{matrix}1 \\ 2 \\3 \end{matrix}\right),\vec{b} \left(\begin{matrix}1 \\ 2 \\3 \end{matrix}\right),\vec{a}\vec{b} \left(\begin{matrix}1 1\\ 2 2 \\3 3 \end{matrix}\right) \left(\begin{matrix}2 \\ 4 \\ 6 \end{matrix}\right) a123,b123,ab112233246 长度 ∣v⃗∣x2y2(1)|\vec{v}|\sqrt{x^2y^2} \tag{1} ∣v∣x2y2(1) 向量相乘
点乘法: a⃗⋅b⃗\vec{a}\cdot\vec{b}a⋅b
a⃗⋅b⃗∣a⃗∣⋅∣b⃗∣⋅cosθ\vec{a} \cdot \vec{b} |\vec{a}|\cdot|\vec{b}|\cdot cos\theta a⋅b∣a∣⋅∣b∣⋅cosθ
叉乘法 : a⃗×b⃗\vec{a}\times\vec{b}a×b 公式如下 a⃗×b⃗(AxAyAz)×(BxByBz)(Ay⋅Bz−Az⋅ByAz⋅Bx−Ax⋅BzAx⋅By−Ay⋅Bx)\vec{a}\times\vec{b} \left( \begin{matrix} \textcolor{#FF0000}{Ax} \\ \textcolor{#00FF00}{Ay} \\ \textcolor{#0000FF}{Az} \end{matrix}\right) \times \left(\begin{matrix} \textcolor{#FF0000}{Bx} \\ \textcolor{#00FF00}{By} \\ \textcolor{#0000FF}{Bz}\end{matrix}\right) \left(\begin{matrix}\textcolor{#00FF00}{Ay} \cdot \textcolor{#0000FF}{Bz} - \textcolor{#0000FF}{Az} \cdot \textcolor{#00FF00}{By} \\ \textcolor{#0000FF}{Az} \cdot \textcolor{#FF0000}{Bx} - \textcolor{#FF0000}{Ax} \cdot \textcolor{#0000FF}{Bz} \\ \textcolor{#FF0000}{Ax} \cdot \textcolor{#00FF00}{By} - \textcolor{#00FF00}{Ay} \cdot \textcolor{#FF0000}{Bx }\end{matrix}\right) a×bAxAyAz×BxByBzAy⋅Bz−Az⋅ByAz⋅Bx−Ax⋅BzAx⋅By−Ay⋅Bx
矩阵
一个矩形的数字、符号或者表达式的数组。矩阵中的每一项叫做矩阵的元素 [011110101]\left[\begin{matrix} 011\\ 110\\ 101\\ \end{matrix}\right] 011110101 矩阵的加减
矩阵与标量之间的加减定义如下 [0111]‾1[0‾11‾11‾11‾1]\left[\begin{matrix} 01\\ 11\\ \end{matrix}\right] \underline 1 \left[\begin{matrix} 0 \underline 11\underline 1\\ 1\underline 11 \underline 1\\ \end{matrix}\right] [0111]1[01111111] 矩阵与矩阵之间的加减就是两个矩阵对应元素的加减运算 [0123]‾[0123][0‾01‾12‾23‾3]加法[0246]减法[0000]\left[\begin{matrix} 01\\ 23\\ \end{matrix}\right] \underline \left[\begin{matrix} 01\\ 23\\ \end{matrix}\right] \left[\begin{matrix} 0\underline01\underline1\\ 2\underline23\underline3\\ \end{matrix}\right] 加法 \left[\begin{matrix} 02\\ 46\\ \end{matrix}\right] 减法 \left[\begin{matrix} 00\\ 00\\ \end{matrix}\right] [0213][0213][00221133]加法[0426]减法[0000] 矩阵的数乘 和矩阵与标量的加减一样矩阵与标量之间的乘法也是矩阵的每一个元素分别乘以该标量。 [0111]⋅2[0⋅21⋅21⋅21⋅2][0222]\left[\begin{matrix} 01\\ 11\\ \end{matrix}\right] \cdot 2 \left[\begin{matrix} 0 \cdot21\cdot 2\\ 1\cdot 21 \cdot 2\\ \end{matrix}\right] \left[\begin{matrix} 02\\ 22\\ \end{matrix}\right] [0111]⋅2[0⋅21⋅21⋅21⋅2][0222] 矩阵相乘 矩阵之间的乘法不见得有多复杂但的确很难让人适应。矩阵乘法基本上意味着遵照规定好的法则进行相乘。当然相乘还有一些限制
只有当左侧矩阵的列数与右侧矩阵的行数相等两个矩阵才能相乘。矩阵相乘不遵守交换律(Commutative)也就是说A⋅B̸B⋅AA \cdot B \not B \cdot AA⋅BB⋅A 公式如下 [1234]⋅[5678][1⋅52⋅71⋅62⋅83⋅54⋅73⋅64⋅8][19224350]\left[\begin{matrix} 12\\ 34\\ \end{matrix}\right] \cdot \left[\begin{matrix} 56\\ 78\\ \end{matrix}\right] \left[\begin{matrix} 1 \cdot 5 2 \cdot 7 1 \cdot 6 2 \cdot 8\\ 3 \cdot 5 4 \cdot 7 3 \cdot 6 4 \cdot 8\\ \end{matrix}\right] \left[\begin{matrix} 1922\\ 4350\\ \end{matrix}\right] [1324]⋅[5768][1⋅52⋅73⋅54⋅71⋅62⋅83⋅64⋅8][19432250]
矩阵与向量相乘
向量就是一个N×1N \times 1N×1的矩阵
单位矩阵就是一个除了对角线以为都是0的 N×NN \times NN×N的矩阵 [1000010000100001]⋅[1234][1⋅12⋅23⋅34⋅4][1234]\left[\begin{matrix} 1000\\ 0100\\ 0010\\ 0001\\ \end{matrix}\right] \cdot \left[\begin{matrix} 1\\ 2\\ 3\\ 4\\ \end{matrix}\right] \left[\begin{matrix} 1 \cdot 1\\ 2 \cdot 2\\ 3 \cdot 3\\ 4 \cdot 4\\ \end{matrix}\right] \left[\begin{matrix} 1\\ 2\\ 3\\ 4\\ \end{matrix}\right] 1000010000100001⋅12341⋅12⋅23⋅34⋅41234 缩放
OpenGL通常是在3D空间进行操作的对于2D的情况我们可以把z轴缩放1倍这样z轴的值就不变了。我们刚刚的缩放操作是不均匀(Non-uniform)缩放因为每个轴的缩放因子(Scaling Factor)都不一样。如果每个轴的缩放因子都一样那么就叫均匀缩放(Uniform Scale)。 [S10000S20000S300001]⋅(xyz1)(S1⋅xS2⋅yS3⋅z1)\left[\begin{matrix} S1000\\ 0S200\\ 00S30\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} S1 \cdot x\\ S2 \cdot y\\ S3 \cdot z\\ 1\\ \end{matrix}\right) S10000S20000S300001⋅xyz1S1⋅xS2⋅yS3⋅z1 位移
位移(Translation)是在原始向量的基础上加上另一个向量从而获得一个在不同位置的新向量的过程从而在位移向量基础上移动了原始向量。我们已经讨论了向量加法所以这应该不会太陌生。
[100Tx010Ty001Tz0001]⋅(xyz1)(xTxyTyzTz1)\left[\begin{matrix} 100Tx\\ 010Ty\\ 001Tz\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} x Tx\\ y Ty\\ z Tz\\ 1\\ \end{matrix}\right) 100001000010TxTyTz1⋅xyz1xTxyTyzTz1 齐次坐标(Homogeneous Coordinates)
向量的w分量也叫齐次坐标。想要从齐次向量得到3D向量我们可以把x、y和z坐标分别除以w坐标。我们通常不会注意这个问题因为w分量通常是1.0。使用齐次坐标有几点好处它允许我们在3D向量上进行位移如果没有w分量我们是不能位移向量的而且下一章我们会用w值创建3D视觉效果。
如果一个向量的齐次坐标是0这个坐标就是方向向量(Direction Vector)因为w坐标是0这个向量就不能位移译注这也就是我们说的不能位移一个方向。
旋转
大多数旋转函数需要用弧度制的角
弧度转角度角度弧度×(180.0/π)角度 弧度 \times (180.0 / \pi)角度弧度×(180.0/π)角度转弧度弧度角度×(π/180.0)弧度 角度 \times (\pi / 180.0)弧度角度×(π/180.0)
沿着x轴旋转 [10000cosθ−sinθ00sinθcosθ00001]⋅(xyz1)(xcosθ⋅y−sinθ⋅zsinθ⋅ycosθ⋅z1)\left[\begin{matrix} 1000\\ 0cos\theta-sin\theta0\\ 0sin\thetacos\theta0\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} x\\ cos\theta\cdot y - sin\theta\cdot z\\ sin\theta\cdot y cos\theta\cdot z\\ 1\\ \end{matrix}\right) 10000cosθsinθ00−sinθcosθ00001⋅xyz1xcosθ⋅y−sinθ⋅zsinθ⋅ycosθ⋅z1 沿着y轴旋转 [cosθ0sinθ00100−sinθ0cosθ00001]⋅(xyz1)(cosθ⋅xsinθ⋅zy−sinθ⋅xcosθ⋅z1)\left[\begin{matrix} cos\theta0sin\theta0\\ 0100\\ -sin\theta0cos\theta0\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} cos\theta\cdot x sin\theta\cdot z\\ y \\ -sin\theta\cdot x cos\theta\cdot z\\ 1\\ \end{matrix}\right) cosθ0−sinθ00100sinθ0cosθ00001⋅xyz1cosθ⋅xsinθ⋅zy−sinθ⋅xcosθ⋅z1 沿着z轴旋转 [cosθ−sinθ00sinθcosθ0000100001]⋅(xyz1)(cosθ⋅x−sinθ⋅ysinθ⋅xcosθ⋅yz1)\left[\begin{matrix} cos\theta-sin\theta00\\ sin\thetacos\theta00\\ 0010\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} cos\theta\cdot x - sin\theta\cdot y\\ sin\theta\cdot x cos\theta\cdot y \\ z \\ 1\\ \end{matrix}\right) cosθsinθ00−sinθcosθ0000100001⋅xyz1cosθ⋅x−sinθ⋅ysinθ⋅xcosθ⋅yz1 矩阵的组合
使用矩阵进行变换的真正力量在于根据矩阵之间的乘法我们可以把多个变换组合到一个矩阵中。让我们看看我们是否能生成一个变换矩阵让它组合多个变换。假设我们有一个顶点(x, y, z)我们希望将其缩放2倍然后位移(1, 2, 3)个单位。我们需要一个位移和缩放矩阵来完成这些变换。结果的变换矩阵看起来像这样 [1001010200130001]⋅[2000020000200001][2001020200230001]\left[\begin{matrix} 1001\\ 0102\\ 0013\\ 0001\\ \end{matrix}\right] \cdot \left[\begin{matrix} 2000\\ 0200\\ 0020\\ 0001\\ \end{matrix}\right] \left[\begin{matrix} 2001\\ 0202\\ 0023\\ 0001\\ \end{matrix}\right] 1000010000101231⋅20000200002000012000020000201231 用最终的变换矩阵左乘我们的向量会得到以下结果: [2001020200230001]⋅(xyz1)(2x12y22z31)\left[\begin{matrix} 2001\\ 0202\\ 0023\\ 0001\\ \end{matrix}\right] \cdot \left(\begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix}\right) \left(\begin{matrix} 2x 1\\ 2y 2\\ 2z 3 \\ 1\\ \end{matrix}\right) 2000020000201231⋅xyz12x12y22z31
代码实现
#version 330 core
layout (location 0) in vec3 aPos;
layout (location 1) in vec3 aColor;
layout (location 1) in vec2 aTexCord;
out vec3 ourColor; // 向片段着色器输出一个颜色
out vec2 texCord; // 向片段着色器输出一个颜色
uniform mat4 RotationMatrix;
void main()
{gl_Position RotationMatrix * vec4(aPos, 1.0);ourColor aColor; // 将ourColor设置为我们从顶点数据那里得到的输入颜色texCord aTexCord;
}QMatrix4x4 matrix;
unsigned int time QTime::currentTime().msec();
matrix.translate(3,3);
matrix.rotate(time, 0.0f, 0.0f, 1.0f);
...
shader_program_.setUniformValue(RotationMatrix, matrix);