title: 计算机图形学 date: 2021-06-10 10:54:17 categories: 学习笔记 tag:
$水平分辨率 垂直分辨率 每个像素所占用的字节$
定义
{% raw %} $$\epsilon = \frac{1}{max(|\Delta x|, |\Delta y|)}$$ {% endraw %}
则递推公式为
{% raw %} $$ \left{ \begin{aligned} x' = Math.round(x + \epsilon \cdot \Delta x) \ y' = Math.round(y + \epsilon \cdot \Delta y) \end{aligned} \right. $$ {% endraw %}
略
假定 $\Delta x > \Delta y$
按照八分法画圆,先绘制 $\frac{\pi}{2} 至 \frac{\pi}{4}$ 的圆,即下图的 $1b$ 区域
定义圆的半径 $R$,则
在区域内部找到一个像素,通过在这个像素的基础上,对邻接的像素进行搜索,并将邻接的像素作为下一个种子
给定的种子点开始,填充当前扫描线上种子点所在的区间,然后确定与这一区间相邻上下两条扫描线上需要填充的区间,在这些区间上取最左侧或最右侧的一个点作为新的种子点。不断重复以上过程,直至所有区间都被处理完
从外部点出发,沿任意方向发射射线,若射线与多边形的交点个数为奇数,则为内部,否则为外部
略
考虑对于每一条直线 $y = kx + b$,当 $y' = y + 1$ 时, $x' = x + \frac{1}{k}$。所以求交点时,若已知一个交点 $(x, y)$,则可以通过上述公式推导出下一个交点为 $(x + \frac{1}{k}, y + 1)$
所以依照上述结论,得出如下的操作(以下图为例)
略
使用齐次坐标表示一个点的坐标
{% raw %} $$ \left( \begin{matrix} x & y \end{matrix} \right) \rightarrow \left( \begin{matrix} x & y & 1 \end{matrix} \right) $$ {% endraw %}
为什么使用齐次坐标系:使图形变换转化为表示图形的点集矩阵与某一变换矩阵相乘,可以借助计算机的高速运算
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 \ 0 & 1 & 0 \ T_x & T_y & 1 \end{matrix}
\left[ \begin{matrix} x + T_x & y + T_y & 1 \end{matrix} \right] $$ {% endraw %}
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} S_x & 0 & 0 \ 0 & S_y & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} xS_x & yS_y & 1 \end{matrix} \right] $$ {% endraw %}
或
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & S \end{matrix}
\left[ \begin{matrix} \frac{x}{S} & \frac{y}{S} & 1 \end{matrix} \right] $$ {% endraw %}
关于原点进行<font color=red>逆</font>时针旋转
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} cos(\theta) & sin(\theta) & 0 \ -sin(\theta) & cos(\theta) & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} xcos(\theta) - ysin(\theta) & xsin(\theta) + ycos(\theta) & 1 \end{matrix} \right] $$ {% endraw %}
关于原点进行<font color=red>顺</font>时针旋转
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} cos(\theta) & -sin(\theta) & 0 \ sin(\theta) & cos(\theta) & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} xcos(\theta) + ysin(\theta) & -xsin(\theta) + ycos(\theta) & 1 \end{matrix} \right] $$ {% endraw %}
关于<font color=red> x </font>轴对称
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 \ 0 & -1 & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} x & -y & 1 \end{matrix} \right] $$ {% endraw %}
关于<font color=red> y </font>轴对称
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} -1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} -x & y & 1 \end{matrix} \right] $$ {% endraw %}
关于<font color=red> 原点 </font>轴对称
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} -1 & 0 & 0 \ 0 & -1 & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} -x & -y & 1 \end{matrix} \right] $$ {% endraw %}
关于<font color=red> $y = x$ </font>轴对称
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 0 & 1 & 0 \ 1 & 0 & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} y & x & 1 \end{matrix} \right] $$ {% endraw %}
关于<font color=red> $y = -x$ </font>轴对称
{% raw %} $$ \left[ \begin{matrix} x' & y' & 1 \end{matrix}
\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 0 & -1 & 0 \ -1 & 0 & 0 \ 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} -y & -x & 1 \end{matrix} \right] $$ {% endraw %}
略
定义
{% raw %} $$\mathbf P = \left[ \begin{matrix} x_1 & y_1 & 1 \ x_2 & y_2 & 1 \ x_3 & y_3 & 1 \ \dots \ x_n & y_n & 1 \end{matrix} \right] $$ {% endraw %}
为这个二维多边形的所有顶点的坐标矩阵,此时再乘上变换矩阵,得到最终结果
先通过平移变换将参考点移动至原点,然后进行变换,然后再重做平移变换进行撤销一开始的变换
先通过旋转变换将参考点移动至原点,然后进行变换,然后再重做旋转变换进行撤销一开始的变换
略
对于点 $P(x, y)$,若满足 $x_{wl} \leq x \leq x_{wr}$ 且 $y_{wb} \leq y \leq y_{wt}$ 则在窗口内,否则在窗口外
对一条直线的两个顶点进行编码
如图,若 $x < x_l$ 则 $D_0 = 1$。若 $x > x_r$ 则 $D_1 = 1$。若 $y < y_b$ 则 $D_2 = 1$。若 $y > y_t$ 则 $D_3 = 1$ 若两个点 $p_1, p_2$ 的编码 $code_1, code_2$ 满足 $code_1 | code_2 = 0$ 则这条直线就在窗口内,若 $code_1 \& code_2 \neq 0$ 则这条直线可以直接抛弃掉。其他情况只需要求出这条直线和四条边的交点即可 所以可以得到如下的流程
计算交点时,可以借用比例的方式计算,例如计算与 $x = x_l$ 的交点时,可以得到
{% raw %} $$ \left{ \begin{aligned} x' & = & x_l \ y' & = & y_1 + (y_2 - y_1) \times (x_l - x_1) / (x_2 - x_1) \end{aligned} \right. $$ {% endraw %}
使用了和 Cohen-Sutherland 完全相同的编码方式,但在求解交点时略有不同。此方法包含一个“求出距离一个点最远的,且在窗口内的点”。所以分别对 $p_1, p_2$ 进行一次求解,并代替掉对方(即对于 $p_1$ 求解的答案,代替掉 $p_2$)即可,以下方法的是对 $p_1$ 进行求解的操作,对 $p_2$ 求解时,交换两个值即可
适合凸多边形,对于凹多边形则需要先分解为多个凸多边形
对于窗口的所有边界,进行一轮裁剪,裁剪对象是多边形的所有的边。
对于一个多边形,可以认为是一系列的顶点集合,顶点之间的连线即为一个多边形。沿着顶点的连线,进行如下的裁剪操作
将所有输出的点连接,得到新的多边形
对于窗口的所有边界都进行一次如上的操作,即可得到最终的图像,例如下图,为左边界对此多边形进行裁剪的结果
从多边形 $P_s$ 的任意一点出发,顺时针遍历所有点
{% raw %} $$ \left[ \begin{matrix} x' & y' & z' & 1 \end{matrix}
\left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 & 0 \ 0 & 1 & 0 & 0 \ 0 & 0 & 1 & 0 \ T_x & T_y & T_z & 1 \end{matrix}
\left[ \begin{matrix} x + T_x & y + T_y & z + T_z & 1 \end{matrix} \right] $$ {% endraw %}
$$ \left[ \begin{matrix} x' & y' & z' & 1 \end{matrix}
\left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \left[ \begin{matrix} a & 0 & 0 & 0 \ 0 & e & 0 & 0 \ 0 & 0 & i & 0 \ 0 & 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} ax & ey & iz & 1 \end{matrix} \right] $$
将右手大拇指指向旋转轴的正方向,然后四个手指的弯曲方向即为正旋转方向
绕<font color=red>z</font>轴旋转
$$ \left[ \begin{matrix} x' & y' & z' & 1 \end{matrix}
\left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \left[ \begin{matrix} cos \theta & sin \theta & 0 & 0 \ -sin \theta & cos \theta & 0 & 0 \ 0 & 0 & 1 & 0 \ 0 & 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} xcos \theta - y sin \theta & xsin \theta + ycos \theta & z & 1 \end{matrix} \right] $$
绕<font color=red>x</font>轴旋转
$$ \left[ \begin{matrix} x' & y' & z' & 1 \end{matrix}
\left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 & 0 \ 0 &cos \theta & sin \theta & 0 \ 0 &-sin \theta & cos \theta & 0 \ 0 & 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} x & ycos \theta - zsin \theta & zsin \theta + zcos \theta & 1 \end{matrix} \right] $$
绕<font color=red>y</font>轴旋转
$$ \left[ \begin{matrix} x' & y' & z' & 1 \end{matrix}
\left[ \begin{matrix} x & y & z & 1 \end{matrix} \right] \left[ \begin{matrix} cos \theta & 0 & -sin \theta & 0 \ 0 & 1 & 0 & 0 \ sin \theta & 0 & cos \theta & 0 \ 0 & 0 & 0 & 1 \end{matrix}
\left[ \begin{matrix} zsin \theta + xcos \theta & y & zcos \theta - xsin \theta & 1 \end{matrix} \right] $$
略
对于 $n$ 个点,用 $n - 1$ 条曲线连接,对于每一条直线看,可以用一个三阶函数表示,所以得到 $$ \left{ \begin{aligned} f_1(x) & = a_1 + b_1x + c_1x^2 + d_1x^3 & x \in [x_0, x_1] \ f_2(x) & = a_2 + b_2x + c_2x^2 + d_2x^3 & x \in [x_1, x_2] \ f_3(x) & = a_3 + b_3x + c_3x^2 + d_3x^3 & x \in [x_2, x_3] \ \dots \ f_n(x) & = a_n + b_nx + c_nx^2 + dnx^3 & x \in [x{n - 1}, x_n] \end{aligned} \right. $$
则对于所有的曲线,由于所有曲线必须保证 G0 连续,所以可以得到如下等式
$$ \left{ \begin{aligned} f_0(x_0) & = & & & y_0 \ f_1(x_1) & = & f_0(x_1) & = & y_1 \ f_2(x_2) & = & f_1(x_2) & = & y_2 \ \dots \ f_n(xn) & = & f{n - 1}(x_n) & = & y_n \ \end{aligned} \right. $$
又为了保证 G1 连续,则可以得到他们的导数相同
$$ \left{ \begin{aligned} f_1'(x_1) & = & f_0'(x_1) \ f_2'(x_2) & = & f_1'(x_2) \ f_3'(x_3) & = & f_2'(x_3) \ \dots \ f_n'(xn) & = & f{n - 1}'(x_n) \ \end{aligned} \right. $$
为了保证 G2 连续,则他们的导数的导数相同,所以还可以得到
$$ \left{ \begin{aligned} f_1''(x_1) & = & f_0''(x_1) \ f_2''(x_2) & = & f_1''(x_2) \ f_3''(x_3) & = & f_2''(x_3) \ \dots \ f_n''(xn) & = & f{n - 1}''(x_n) \ \end{aligned} \right. $$
由此,可以计算出所有的参数
$$P(t) = \sum^n_{k=0}PkBEN{k, n}, t \in [0, 1]$$
$$BEN_{k, n}(t) = \frac{n!}{k!(n - k)!}t^k(1 - t)^{n - k} = C^k_nt^k(1 - t) ^ {n - k}$$
$$P'(0) = n(P_1 - P_0)$$
$$P'(1) = n(Pn - P{n - 1})$$
$$P''(0) = n(n - 1)((P_2 - P_1) - (P_1 - P_0))$$
$$P''(1) = n(n - 1)((P{n - 2} - P{n - 1}) - (P_{n - 1} - P_n))$$
颠倒控制顶点,Bézier 曲线仍然保持,走向相反
略
Bézier 曲线与坐标轴无关
由于一阶导数可知,若需要满足 G1 连续,则必须要满足第一条曲线的最后两个控制点和第二条曲线的开始两个控制点在同一条直线上,且保证不在同一侧,即
$$(Pn - P{n - 1}) = \alpha (Q_1 - Q_0')$$
$$((P{n - 2} - P{n - 1}) - (P_{n - 1} - P_n)) = \beta ((Q_2 - Q_1) - (Q_1 - Q_0))$$
向 z 轴的负方向作为观察方向,以其 z 轴的大小作为深度值,保存每一个像素的颜色值和深度值,当此像素被再次覆盖时,若新的深度比之前保存的大,则用新的深度和颜色覆盖之前的值,否则不更换
将物品从远到近排列,先绘制远处的图形,再由近处的图形进行覆盖
对于屏幕上的每一个像素点,构造一条模拟视线的射线,由射线的交点来确定深度最大的点
用于物体表面采样点处光强度的计算
取一个平面内的任意一个点的光强来表示整个平面的光强
计算量非常小,粗糙,亮度变化大,出现马赫带效应
根据多边形在顶点处的光强,线性插值求出平面内其他点的光强
计算量小,算法简单,出现马赫带效应,对镜面反射效果不佳
根据多边形在顶点处的法向量,线性插值求出平面内其他点的法向量
计算量大,效果好,精度高
基于几何光学原理,模拟光的传播路径来确定反射、折射和阴影。通过“过采样”的方式,实现反走样