[Day10] 2D的数学世界(二) - 座标系转换

本篇没有实作,仅数学理解内容
今天的内容,可能有点长,会拆成两篇 - 2D的数学世界(三) (谜: 爽啦?!有水了一回)

今日目标

  • 理解座标系转换

之前的DrawTexture

之前画的兔子,不只倒着,还有中年发福的迹象,发福的原因在於,预设所使用的座标

// 每行前两个是顶点座标的XY
static const float VERTICES[] = {
	0.5f,  0.5f, 1.0f, 1.0f,	// top right
    0.5f, -0.5f, 1.0f, 0.0f, 	// bottom right
    -0.5f, -0.5f, 0.0f, 0.0f, 	// bottom left
    -0.5f,  0.5f, 0.0f, 1.0f	// top left 
};

换个角度观察可以知道一件事,明明顶点的座标这麽小,解析度有800x600,可是为什麽看起来已经占了1/4的萤幕了?其原因则在於座标系上。

座标系

笛卡尔座标,这个从国小就开始接触的座标系,简单的在纸上换上两条垂直交叉的线,2D世界的雏型就出来了。除了常见的笛卡尔座标系,还有极座标系、球座标系和齐次座标系(这个後面会用到)。

接下来谈谈座标系转换,我的用词可能是错误的,也请纠正,这里仅写上我的理解还请见谅:

我们拿笛卡尔、极座标系来说明,如果用这两个不同的座标系在2D上作图,最终结果都只会看到一个点,或是一条线(向量)。既使最终描绘的点一样,这两个最大的不同是他们的基底(Basis)不一样,也是说同一个点,不同坐标系上,描述的情况不一样,以笛卡尔来说:

// 假如要动X轴,那"基底向量"就是
| 1 |
| 0 |

// 假如要动Y轴,那"基底向量"就是
| 0 |
| 1 |

// 把这两个向量形成一个矩阵
| 1  0 |
| 0  1 |

最後范例里的矩阵,就是"基底(Basis)",我们可以用这个矩阵来构筑2D世界,只要这样作

// 这里的x, y先不视为座标上的x, y
// 而是对於"基底向量"的延伸(scalar)
// 如: x 就是对基底向量 (1, 0)的延伸,之後就变成(x, 0)

| 1  0 | | x |
| 0  1 | | y |

就可以到一个平面上的任意点,这个叫做"线性生成空间(Span)",没错,这样一个空间就诞生了。

那以极座标来说,他的基底就会是

// 令角度为theta
| cos(theta)      0    |
|      0    sin(theta) |

如果要从A座标系转换到B座标系,我们只要找到转换矩阵就可以把A座标系的向量X转换到座标系B。举个例来说,这边我用unity举例,用过的小夥伴,应该听过这两个

localPositon
Position

这两个就是描述不同座标系底下的座标位置,localPosition是物件本身,你可以看成是模型本身,以自身为原点画出的座标;Position则是世界座标,是以世界为中心点画出来的座标。

其实最後要说明的就是这件事,最开始画的矩形,并不是在800x600的这个座标系(世界座标)上,而是OpenGL本身的座标系-Normalized Device Coordinate, NDC上,这个座标系三轴(x, y, z)的范围都是[-1, 1],所以才会看到以每个象限0.5为顶点的矩形,会长在中间,并占了整个画面的1/4。

接下来就是要对四个顶点座标,转换到800x600的世界里面...

MVP matrix

回到预设的vertex shader上,原本各为0.5的座标是上面所提到的localPosition,我们要把他换到世界座标上,这边会需要一个转换的矩阵。但除了世界座标还不够,我们要观看这个世界还需要一个小窗口也可以说是相机,去观看世界,这里也会需要一个矩阵。然後我们还要决定看过去的景象是透视(往远处延伸到一点)还是正投影(没有透视效果),这个空间会叫作齐次座标空间,最後还要把矩形转换到NDC上,也就是萤幕空间。

整理一下:

本地(?)座标 -> [模型矩阵] -> 世界座标 -> [视角矩阵] -> 相机空间 -> [透视矩阵] -> 齐次座标空间

那这些矩阵合而为一,就会是所谓的MVP矩阵。

最後换到齐次座标空间原因是,齐次坐标可让包括无穷远点的点坐标以有限坐标表示(from wiki),转到世界空间时就是了,XY两轴并终点是无穷大,但我们需要把我们的矩形放到NDC里面,这就需要换到齐次空间了。

实作规划

这里是先跳过相机视角,因为这还要处理相机的移动,之後会再相机篇的时候加进去,所以会先跳过视角矩阵的部分;透视(Perspective)还是正投影(Orthographic),因为只是在2D内所以透视矩阵会是正投影的方式。

所以目前MVP的矩阵,只会是MP的部分。

再来其实就是矩阵的运算了,请注意,通常我们看数学算式都是从左到右,但矩阵的计算会是从右到左

首先是模型(Model)矩阵,测试用的,直接产在原点上,主要要处理的就是实作,正投影的功能。

如何实作我是参考这篇的OpenGL Projection Matrix

参考


<<:  D20 - 如何用 Apps Script 自动化地创造与客制 Google Slides?(一)架构拆解与更改文字

>>:  [Day_6]资料型别、变数与运算子 - 练习题

Day21 - 预览页加入按纽

今天状况不佳,稍微休息一下。 在Day02的时候有先粗略摆放预览页的几个按钮: 今天没什麽内容,就把...

DAY25-EXCEL统计分析:共变数实例

有一位学生想知道每天读书时间与考试成绩之间的线性相关程度,所以蒐集了每次期中期末考的国英数自社的成绩...

[Day02] - 旅途开始前的行前解说

昨天提到了 Web Component , 今天先初步了解一下什麽是 WebComponent 跟他...

day21 开分支,浅谈kotlin paging3 with flow

注意,我只讲了codelab的50%左右,但对paging3和flow的概念讲完了 通常有codel...

远端系列-5:如何拉回远端数据库的档案?

角色情境 小明同时学会输入指令操作着终端机、 以及透过滑鼠操作着图像化介面的 Sourcetree ...