图形学数学笔记-043D几何学

3D几何学

直线

通过点\mathbf{P}_{0},走向与方向\mathbf{V}平行的直线可表示为
\mathbf{P}(t)=\mathbf{P}_{0}+t\mathbf{V}
从点\mathbf{Q}到直线\mathbf{P}(t)的距离d等于
d=\sqrt{(\mathbf{Q}-\mathbf{P}_{0})^{2}-\frac{\lbrack (\mathbf{Q}- \mathbf{P}_{0}) \cdot \mathbf{V}\rbrack^{2}}{\mathbf{V}^{2}}}
设直线方向为\mathbf{V}_{1},\mathbf{V}_{2},则判断两条直线平行的条件是:
(\mathbf{V}_{1}\cdot \mathbf{V}_{2})^{2}-\mathbf{V}_{1}^{2}\mathbf{V}_{2}^{2}=0

平面

法向量为\mathbf{N}并包含点\mathbf{P}_{0}的平面表达式为
\mathbf{N} \cdot \mathbf{P}+D=0
其中,D=-\mathbf{N} \cdot \mathbf{P}_{0}。平面也可以表示成\mathbf{L} \cdot \mathbf{P}=0,其中\mathbf{L}为四维坐标\langle \mathbf{N},D \rangle\mathbf{P}w坐标为1的四维齐次坐标点。点\mathbf{Q}到平面\mathbf{L}的距离为\mathbf{L} \cdot \mathbf{Q}。

直线与平面相交

直线\mathbf{P}(t)=\mathbf{Q}+t\mathbf{V}与平面\mathbf{L}的交点处的t值为
t=-\frac{\mathbf{L} \cdot \mathbf{Q}}{\mathbf{L} \cdot \mathbf{V}}

平面相交

\mathbf{L}_{1}=\langle\mathbf{N}_{1},D_{1}\rangle,\mathbf{L}_{2}=\langle\mathbf{N}_{2},D_{2}\rangle,\mathbf{L}_{3}=\langle\mathbf{N}_{3},D_{3}\rangle为三个任意平面,令:
\mathbf{Q}=\mathbf{M}^{-1}\left[\begin{array}{c}{-D_{1}}\\{-D_{2}}\\{-D_{3}}\end{array} \right]
其中
\mathbf{M}=\left[ \begin{array}{c}{(\mathbf{N}_{1})_{x}}&{(\mathbf{N}_{1})_{y}}&{(\mathbf{N}_{1})_{z}}\\{(\mathbf{N}_{2})_{x}}&{(\mathbf{N}_{2})_{y}}&{(\mathbf{N}_{2})_{z}}\\{(\mathbf{N}_{3})_{x}}&{(\mathbf{N}_{3})_{y}}&{(\mathbf{N}_{3})_{z}}\end{array}\right]
如果\mathbf{M}是奇异矩阵,即\det\mathbf{M}=0,则三个平面不交于一点。

设令\mathbf{L}_{1}=\langle\mathbf{N}_{1},D_{1}\rangle,\mathbf{L}_{2}=\langle\mathbf{N}_{2},D_{2}\rangle相交,交于一条直线,则可表示\mathbf{V}=\mathbf{N}_{1}\times\mathbf{N}_{2}。

交线的表达式为\mathbf{P}(t)=\mathbf{Q}+t\mathbf{V}

其中
\mathbf{Q}=\left[ \begin{array}{c}{(\mathbf{N}_{1})_{x}}&{(\mathbf{N}_{1})_{y}}&{(\mathbf{N}_{1})_{z}}\\{(\mathbf{N}_{2})_{x}}&{(\mathbf{N}_{2})_{y}}&{(\mathbf{N}_{2})_{z}}\\{\mathbf{V}_{x}}&{\mathbf{V}_{y}}&{\mathbf{V}_{z}}\end{array}\right]^{-1}\left[\begin{array}{c}{-D_{1}}\\{-D_{2}}\\{0}\end{array} \right]

视锥

视锥中,与水平视场角\alpha。对应的焦距e的表达式为
e=\frac{1}{\tan(\alpha/2)}
焦距越短,则视场越大,视场角逐渐缩小,相机则进行放大成像,而焦距越大。

垂直视场角\beta的表达式为
\beta = 2\tan^{-1}(a/e)
对于高宽比为a的显示器,从与相机距离为n的近锥平面中裁剪出的矩形的边分别为x= \pm n/ey=\pm an/e。

透视校正插值

在透视投影中,利用相似三角形,对深度z_{1}z_{2}的倒数可进行线性插值:
\frac{1}{z_{3}}=\frac{1}{z_{1}}(1-t)+\frac{1}{z_{2}}t
带透视校正的顶点属性插值可由以下类似的公式获得:
\begin{aligned}\because &z_{3}=\frac{1}{\frac{1}{z_{1}}(1-t)+\frac{1}{z_{2}}t}\\&b_{3}=\frac{b_{1}z_{2}(1-t)+b_{2}z_{1}t}{z_{2}(1-t)+z_{1}t}\\\therefore &\frac{b_{3}}{z_{3}}=\lbrack \frac{b_{1}}{z_{1}}(1-t)+\frac{b_{2}}{z_{2}}t \rbrack\end{aligned}
其中,b_{1}b_{2}为顶点属性值,表明三角形面上的插值属性与z坐标值的倒数的乘积b/z是线性插值。

投影

为了将一个三维场景渲染在一个二维显示器屏幕上,场景中的每个顶点在屏幕上显示位置。如前所述,对于位于点\mathbf{P}的一个顶点,通过计算从原点发出的照向点\mathbf{P}的一束光线与投影平面交点,可求得该顶点在投影平面的投影位置。投影点的xy坐标的表达式如下:
\begin{aligned}{x=-\frac{e}{\mathbf{P}_{z}}\mathbf{P}_{x}}\\{y=-\frac{e}{\mathbf{P}_{z}}\mathbf{P}_{y}}\end{aligned}
这里需注意的是\mathbf{P}_{z}的值是负的,因为相机指向z坐标轴的负向。
z坐标应用式只会得到投影深度值-e,然而深度信息可用于隐藏面剔除算法,因此3D图形系统使用四维空间的齐次坐标对顶点进行投影。

透视投影

透视投影可将顶点的xy坐标投影到投影平面的正确位置,而同时保留深度信息。通过将视锥映射成立方体可实现透视投影,该立方体是所谓的齐次裁剪空间在3D空间的投影,在OpenGL中,它的中心与坐标系原点重合,分别沿x,y,z坐标轴-1扩展到+1

到齐次裁剪空间的映射首先用一个4 \times 4投影矩阵将相机空间的点的负z坐标添加到变换点的w坐标,接着除以w坐标则得到一个有规范化设备坐标的三维点。

\mathbf{P}=\langle P_{x},P_{y},P_{z},1\rangle是相机空间中的一个齐次坐标点,该点位于视锥内部。在OpenGL中,函数gIFrustum();的参数包括一个矩形的四条边,函数申城透视投影矩阵。

将相机空间的点变换到裁剪空间的透视投影矩阵\mathbf{M}_{\text{frustum}}
\mathbf{M}_{\text{frustum}}=\left[\begin{array}{cccc}{\frac{2 n}{r-l}} & {0} & {\frac{r+l}{r-l}} & {0} \\ {0} & {\frac{2 n}{t-b}} & {\frac{t+b}{t-b}} & {0} \\ {0} & {0} & {-\frac{f+n}{f-n}} & {-\frac{2 n f}{f-n}} \\ {0} & {0} & {-1} & {0}\end{array}\right]
其中,nf分别是从相机到近锥平面和远锥平面的距离,l,r,b,t分别是从近锥平面裁剪出来的观察矩形的左、右、底和顶边。

通过使远锥平面的距离f趋于无穷大,可以构造一个无限视锥,符合规范化设备坐标系(NDC),相应的投影矩阵为
\mathbf{M}_{\text{infinity}}=\lim_{f \to \infty}{\mathbf{M}_{\text{frustum}}}=\left[\begin{array}{cccc}{\frac{2 n}{r-l}} & {0} & {\frac{r+l}{r-l}} & {0} \\ {0} & {\frac{2 n}{t-b}} & {\frac{t+b}{t-b}} & {0} \\ {0} & {0} & {-1} & {-2n} \\ {0} & {0} & {-1} & {0}\end{array}\right]

正投影

相机空间的点总是被与相机观察方向平行的光线映射到投影平面。

正投影的可见区由一个位于x-y平面的矩形、近平面和远平面距离组成。由于不存在透视扭曲,正投影中的三角形的深度可用线性插值获得,因此,向规范化设备坐标系的映射可分别在三个坐标轴上线性执行。

xy坐标分别从区间\lbrack l,r\rbrack,\lbrack b,t\rbrack,\lbrack -f,-n\rbrack映射到\lbrack -1,1\rbrack区间的函数为
\begin{aligned}{x^{\prime}=\frac{2}{r-l}x-\frac{r+l}{r-l}}\\{y^{\prime}=\frac{2}{t-b}x-\frac{t+b}{t-b}}\\{z^{\prime}=\frac{-2}{f-n}x-\frac{f+n}{f-n}}\end{aligned}
将三个映射函数写成矩阵的形式,可得
\mathbf{P}^{\prime}=\mathbf{M}_{\text{ortho}} \mathbf{P}=\left[\begin{array}{cccc}{\frac{2}{r-l}} & {0} & {0} & {-\frac{r+l}{r-l}} \\ {0} & {\frac{2}{t-b}} & {0} & {-\frac{t+b}{t-b}} \\ {0} & {0} & {\frac{-2}{f-n}} & {-\frac{f+n}{f-n}} \\ {0} & {0} & {0} & {1}\end{array}\right]\left[\begin{array}{l}{P_{x}} \\ {P_{y}} \\ {P_{z}} \\ {1}\end{array}\right]
矩阵\mathbf{M}_{\text{ortho}}是OpenGL中由glOrtho();函数产生的正投影矩阵。注意,变换后w坐标为1,不会发生透视投影。

镜像与倾斜裁剪

在很多场景中,包含像镜面或者水体一类的反射表面,需要渲染这些表面中的反射图像。

显示场景中的反射图像的典型方法是建立一个专门的图像缓存区,即所谓的反射缓存,来保存场最中在反射面中可见对象的道染结果,而主场景仍然保存到主图像缓存区。当渲染反射表面的几何对象时,从反射缓存区读出相应对象的颜色混合到最终图像中。

反射场景通过一个虚拟相机渲染,该虚拟相机是主相机关于反射平面的镜像。

由于虚拟相机是原相机的反射,则虚拟相机坐标系由反射前的右手坐标系变成左手坐标系,为了适应这个变化必须采用一些专门的操作。在OpenGL中,通过调用函数glFrontFace();可容易地翻转前向三角形的坐标顺序使其适合裁剪。

在处理虚拟相机渲染时,一些几何体与相机之间的距离比反射平面到相机的距离近。当一个物体位于反射平面两侧时会发生这种情况,这时位于反射平面背面的部分在反射过程中将被翻转,如果该几何体在反射过程中被渲染,则会在最终的渲染图像中产生一些不需要的结果。

这类问题的一个最简单解决办法是定义一个用户裁剪平面将位于反射表面的几何体裁剪掉,而不幸的是,尽管大多数GPU支持普通的用户自定义裁剪平面,而在使用时需要修改顶点或者段程序,这将带来一些麻烦,因为在渲染某一个几何体时要保存两个不同版本的顶点或者段程序,而且在不同的GPU之间实现方法也会有稍微的差异。

倾斜近锥平面裁剪

将透视投影矩阵\mathbf{M}变换为以下矩阵\mathbf{M}',可将近锥平面变换为相机空间的裁剪平面\mathbf{C},其中C_{w} < 0
\mathbf{M}'=\left[\begin{array}{c}{\mathbf{M}_{1}}\\{\mathbf{M}_{2}}\\{\frac{-2Q_{z}}{\mathbf{C}\cdot\mathbf{Q}}\mathbf{C}+\langle 0,0,1,0 \rangle}\\{\mathbf{M}_{4}} \end{array} \right]
其中,\mathbf{Q}=\mathbf{M}^{-1}\mathbf{Q}'\mathbf{Q}'=\langle sgn(C'_{x}),sgn(C'_{y}),1,1 \rangle。

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容