计算机图形学算法总结

图形学算法总结

直线生成算法

数值微分法(DDA)

y = k x + b y = kx + b y=kx+b

x每增加1,y增量为k

|k|要小于1,大于则互换x,y

原因:防止画出来的线太稀疏

image-20201216201300050
象限|dx|>|dy|?D xD y
1a1k
1b1/k1
2a-1k
2b-1/k1
3a-1-k
3b-1/k-1
4a1-k
4b1/k-1

中点画线法

image-20201214170017854

y = a x + b y + c y = ax + by +c y=ax+by+c

其中, a = y 0 − y 1 , b = x 1 − x 0 a=y_0-y_1,b=x_1-x_0 a=y0y1b=x1x0

我们每次都把中点(x+1,y+0.5)带入方程,记结果为d,与0比较

  • d≥0 中点在直线上方,取 ( x i + 1 , y i ) (x_i+1,y_i) xi1yi

    • d i + 1 = d i + a d_{i+1}=d_i+a di+1=di+a
  • d<0 中点在直线下方,取 ( x i + 1 , y i + 1 ) (x_i+1,y_i+1) xi1yi1

    • d i + 1 = d i + a + b d_{i+1}=d_i+a+b di+1=di+a+b

其中,初始值 d 0 = a + 0.5 b d_0 = a+0.5b d0=a+0.5b

可以用 2d 代替 d 来摆脱小数,提高效率。

image-20201214210605635

Bresenham算法

image-20201214212300608

我们计算直线的斜率 k = d y d x k=\frac{dy}{dx} k=dxdy

和DDA一样,x每增加1,y增加k

于是,我们可以这样算:

d 0 = 0 d_0=0 d0=0 d i + 1 = d i + k d_{i+1} = d_i+k di+1=di+k

  • d≥0.5 取 ( x i + 1 , y i + 1 ) (x_i+1,y_i+1) xi1yi1
  • d<0.5 取 ( x i + 1 , y i ) (x_i+1,y_i) xi1yi

当 d≥1 的时候 d = d − 1 d = d-1 d=d1

当然,为了便于计算,可令 e = d − 0.5 e = d-0.5 e=d0.5

e 0 = − 0.5 e_0=-0.5 e0=0.5 e i + 1 = e i + k e_{i+1} = e_i+k ei+1=ei+k

  • e≥0 取 ( x i + 1 , y i + 1 ) (x_i+1,y_i+1) xi1yi1
  • e<0 取 ( x i + 1 , y i ) (x_i+1,y_i) xi1yi

当 e≥0 的时候 e = e − 1 e = e-1 e=e1

image-20201214222155793

圆弧生成算法

中点Bresenham画圆法

image-20201214225242102

d = x 2 + y 2 − R 2 d = x^2+y^2-R^2 d=x2+y2R2

与前面类似 d 0 = 1.25 − R d_0=1.25-R d0=1.25R

  • d≥0 取 ( x i + 1 , y i − 1 ) (x_i+1,y_i-1) (xi1yi1)
    • d i + 1 = d i + 2 ( x p − y p ) + 5 d_{i+1}=d_i+2(x_p-y_p)+5 di+1=di+2(xpyp)+5
  • d<0 取 ( x i + 1 , y i ) (x_i+1,y_i) (xi1yi)
    • d i + 1 = d i + + 2 x p + 3 d_{i+1}=d_i++2x_p+3 di+1=di++2xp+3

为方便计算,使用e=d-0.25代替d

多边形填充算法

逐点判断法

1)射线法

作射线求交点各数k

  • k为奇数 点在多边形内
  • k为偶数 点在多边形外

特殊情况:

image-20201215102939831
2)累计角度法
image-20201215103310138

与各顶点连线,形成有向角 θ i \theta_i θi,然后作累加

  • 结果为0 点在多边形外
  • 结果为±2 π \pi π 点在多边形内

扫描线算法(YX)

image-20201215104101448

举个例子,6号扫描线与多边形交点并按x值递增排序为A,B,C,D

然后我们就开始配对,AB一对,CD一堆,并给AB和CD这两个线段填色。

依此类推,就能给多边形填完色。

改进的扫描线算法(Y-X)

image-20201215104101448

活性边表: x x x △ x △x x y m a x y_{max} ymax

image-20201215105032090

边表桶:

image-20201215105754025

特殊情况:

  • 水平边扔掉

  • X为小数

    image-20201215112134796
    • (a)交点位于左边上,向右取整
    • (b)交点位于右边上,向左取整
  • (x,e)落在像素上

    image-20201215112119022
    • (a)(x,e)位于左边上,属于多边形
    • (b)(x,e)位于右边上,不属于多边形
  • 交点位多边形的顶点(下闭上开)

    image-20201215112435378

    应该是指经过P1的点

    • (a) 算作1个交点
    • (b) 算作1个交点
    • © 算作2个交点
    • (d) 算作0个交点

边缘填充算法

对多边形上每一条非水平边上的每个象素开始向右求余

image-20201215114446646

改进后有栅栏填充算法边界标志算法

区域种子填充算法

image-20201215120839485
1)深度递归的种子填充算法(漫水法)
  1. 种子入栈

  2. 栈非空,转3;栈空,结束

  3. 栈顶元素出栈,如果它未填充则填充,然后找其他方向未填充的点,将其入栈,找完所有方向后(4联通就是4个方向,8联通就是8个方向),转2

image-20201215133136964

假设方向是上下左右,那么顺序就是

  1. 栈:H
  2. 填色:H 栈: I F J
  3. 填色:J 栈:I F K N
  4. 填色:N 栈:I F K M
  5. 填色:M 栈:I F K L
  6. 填色:L 栈:I F K
  7. 填色:K 栈:I F
  8. 填色:F 栈:I D G
  9. 填色:G 栈:I D E
  10. 填色:E 栈:I D
  11. 填色:D 栈:I C
  12. 填色:C 栈:I B
  13. 填色:B 栈:I A
  14. 填色:A 栈:I
  15. 填色:I
2)扫描线种子填充算法

其实就是种子填充的改进版,减少了递归次数

扫描线种子填充算法

  1. 初始化:堆栈置空。将种子点(x,y)入栈。

  2. 出栈:若栈空则结束。否则取栈顶元素(x,y),以y作为当前扫描线。

  3. 填充并确定种子点所在区段:从种子点(x,y)出发,沿当前扫描线向左、右两个方向填充,直到非内部。分别标记区段的左、右端点坐标为xl和xr。

  4. 并确定新的种子点:在区间[xl,xr]中检查与当前扫描线y上、下相邻的两条扫描线上的象素。若存在非边界、未填充的象素,则把每一区间的最右象素作为种子点压入堆栈,返回第(2)步。

image-20201215133136964
  1. 填充DFHJM
  2. 上下搜寻
    1. DFHJM任意一个往下走填充EDIK
    2. N往上走填充M
    3. D往上走填充C
  3. 上下搜寻
    1. M往上走填充L
    2. C往上走填充B
  4. 上下搜寻
    1. B往上走填充A

反走样

有两个方式,一个是提高分辨率,另一个是改进算法,这里当然讲算法喽

简单区域采样(非加权区域采样)

根据面积改变亮度达到反走样效果

image-20201215134428451

面积计算(m是斜率,像素宽为1)

  • 情况(1)(5)阴影面积为: D 2 2 m \frac{D^2}{2m} 2mD2
  • 情况(2)(4)阴影面积为: D − m 2 D - \frac{m}{2} D2m
  • 情况(3)阴影面积为: 1 − D 2 m 1-\frac{D^2}{m} 1mD2

上述阴影面积是介于0-1之间的正数,用它乘以象素的最大灰度值,再取整,即可得到象素的显示灰度值。

加权区域采样

其实就是在非加权区域采样的基础上加了个权值来表示与中心距离,然后计算灰度的时候要考虑这个权值。

image-20201215140445480 image-20201215140514007

直线和多边形裁剪

编码裁剪

D 3 D 2 D 1 D 0 D_3D_2D_1D_0 D3D2D1D0分别表示是否上于上边界,是否下于下边界,是否右于右边界,是否左于左边界

  • 是为1,否为0
image-20201215142633242
  • P 1 P 2 P_1P_2 P1P2完全在窗口内(code1 || code2) = 0, 则“取”
  • P 1 P 2 P_1P_2 P1P2明显在窗口外(code1 & code2) ≠ 0, 则“弃”
  • 在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理

中点分割裁剪

和编码的区别在于最后一步,不是交点处分为两段,而是中点处,然后不断二分,把完全在窗口外的舍弃,直到精度满足要求。

梁友栋-Barskey算法

image-20201215145701885

首先,我们将这个线段确定一个方向,然后将线段和窗口延长,得到四个交点,记为 r 1 , r 2 , r 3 , r 4 r1,r2,r3,r4 r1,r2,r3,r4(这也是它们的横坐标)

这样,我们得到两个入边和两个出边(PPT上叫始边和终边)

这样我们要裁剪得到的线段的两个端点的横坐标 u 1 u 2 u_1u_2 u1u2就可以确定了

  • u 1 = m a x ( 0 , x 入 边 1 , x 入 边 2 ) u1 = max(0, x_{入边1},x_{入边2}) u1=max(0,x1,x2)
  • u 2 = m i n ( 1 , x 出 边 1 , x 出 边 2 ) u2 = min(1, x_{出边1},x_{出边2}) u2=min(1,x1,x2)

那么我们要如何确定入边出边呢?

image-20201216220340696

每个交点的横坐标为 r k = q k p k r_k = \frac{q_k}{p_k} rk=pkqk

如果 p k ≠ 0 p_k \neq 0 pk=0

  • p k < 0 p_k<0 pk<0 入边
  • p k > 0 p_k>0 pk>0 出边

多边形逐边裁剪算法

多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种:

image-20201215155602663

情况(1)仅输出顶点P;

情况(2)输出0个顶点

情况(3)输出线段SP与裁剪线的交点 I

情况(4)输出线段SP与裁剪线的交点 I 和终点 P

image-20201216221317949

双边裁剪算法

这个我还没实践过,所以直接粘贴下PPT。算法思想的话,PPT上这个够看了。

简单来说,就是我们的裁剪窗口不再是矩形了,而是一个多边形。

image-20201215155954550 image-20201215160008138

算法思想

  1. 计算主多边形与裁剪多边形的交点
  2. 如果主多边形与裁剪多边形有交点,则交点成对出现,它们被分为如下两类
    1. 进点:主多边形边界由此进入裁剪多边形内
    2. 出点:主多边形边界由此离开裁剪多边形区域
  3. 跟踪任意一个交点
  4. 如果为进点,则跟踪主多边形边界
  5. 如果为出点,则跟踪裁剪多边形边界
  6. 任选一个没有跟踪过的交点,按上述过程重新搜索,直至所有交点跟踪完毕
  7. 如果该交点为进点,跟踪主多边形边边界;否则跟踪裁剪多边形边界
  8. 跟踪多边形边界,每遇到多边形顶点,将其输出到结果多边形顶点表中,直至遇到新的交点
  9. 将该交点输出到结果多边形顶点表中,并通过连接该交点的双向指针改变跟踪方向(如果上一步跟踪的是主多边形边界,现在改为跟踪裁剪多边形边界;如果上一步跟踪裁剪多边形边界,现在改为跟踪主多边形边界)
  10. 重复(4)、(5)直至回到起点

消隐

深度缓存算法(Z_Buffer算法)

加入一个深度缓存数组z[m][n]来存最小深度值

加入一个帧缓存数组FB[m][n]来存像素点对应颜色值

每个像素点上放深度最小的多边形的颜色

扫描线算法

image-20201216223622622

扫描线的交点把这条扫描线分成了若干个区间,每个区间上必然是同样一种颜色

对于有重合的区间,如** a 6 a 7 a_6a_7 a6a7**这个区间,要么显示F2的颜色,要么显示F3的颜色,不会出现颜色的跳跃

如果把扫描线和多边形的这些交点都求出来,对每个区间,只要判断一个像素的要什么颜色,那么整个区间的颜色都解决了,这就是区间扫描线算法的主要思想。

需要的数据结构有很多,比如多边形y桶、有效多边形表APT、边Y桶、有效边表AET,具体这些是啥,看PPT吧

多边形区域排序算法

在规则化图像空间中,将多边形按深度Z值自小至大排序,用前面的可见多边形去切割其后面的多边形,使得最终每一个多边形要么是完全可见,要么完全不可见。

曲线曲面

我这里写得有点点乱,以后有空再修改吧。

Hermite曲线

image-20201216231503357image-20201216231519275

image-20201216231519275

image-20201216231543617

Bezier曲线

image-20201216225144647

P i P_i Pi是控制点

有n个控制点,那么曲线的阶数就是n-1,计算量巨大

Bezier曲线的性质

  • 端点性质 曲线过两端点且与端点相切
  • 对称性: 若保持n次Bezier曲线的顶点的位置不变,而把次序颠倒,则曲线保持不变
  • 凸包性: 伯恩斯坦多项式各项之和为1。这意味着Bezier曲线各点均落在特征多边形顶点构成的凸包之中
  • 几何不变性:曲线的形状仅与特征多边形个顶点的相对位置有关,而与坐标的选择无关

B样条曲线

image-20201216230724695

这个图是PPT上的,和我下面的有些许不同,但实际是一样的。

image-20201216232842500

这个图是我要讲的,下面就逐步来解释

啥是B样条曲线?

整条曲线用一个完整的表达形式,但内在的量是一段一段的,比如一堆的3次曲线拼过去,两条之间满足2次连续

怎么分段呢?

image-20201216230333734

每一段的基函数怎么求?

de Boor-Cox递推定义

只要是k阶(k-1次)的B样条基函数,构造一种递推的公式,由0次构造1次,1次构造2次,2次构造3次…依次类推

image-20201216232056543

B样条函数定义区间 u ∈ [ u k − 1 , u n + 1 ] u\in[u_{k-1},u_{n+1}] u[uk1,un+1] 是怎么来的?

image-20201216231744567

image-20201216232640175image-20201216232717018

image-20201216232717018

image-20201216232741331 image-20201216233106742

B样条曲线的性质

  • 端点性质与连续性
  • 当t=0 或 t=1分别代入三次B样条方程得:
    P ( 0 ) = 1 / 3 ∗ ( ( p i + p i + 2 ) / 2 + 2 p i + 1 ) P(0)=1/3*((p_i+p_{i+2})/2+2p_{i+1}) P(0)=1/3((pi+pi+2)/2+2pi+1)
    P ( 1 ) = 1 / 3 ∗ ( ( p i + 1 + p i + 3 ) / 2 + 2 p i + 2 ) P(1)=1/3*((p_{i+1}+p_{i+3})/2+2p_{i+2}) P(1)=1/3((pi+1+pi+3)/2+2pi+2)
    三次B样条在连接处的一阶导数、二阶导数都是连续的。‘
  • 局部性:改变一个控制点的位置,最多影响四个曲线段。由此三次B样条具有改变控制点的位置就可以对B样条局部修改曲线
  • 扩展性:增加一个控制点就相应增加一段B样条曲线,而原有曲线不受任何影响

图形变换

平移变换

二维

image-20201216233949685

三维

image-20201216234225576

比例变换

二维

image-20201216234026885

三维

image-20201216234255958

旋转变换

二维

image-20201216234047706

三维

绕z轴旋转

image-20201216234349682

绕x轴旋转

image-20201216234411170

绕y轴旋转

image-20201216234431295

对称变换

image-20201216234127511

错切变换

image-20201216234146319

投影变换

正交平行投影

image-20201216234543871image-20201217091914775

image-20201216234543871image-20201217091914775

斜交投影
image-20201216234627487 image-20201216234638857
透视投影
image-20201216234729308
  • 19
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
现代计算机图形学是一个涵盖了计算机科学、数学和物理学等多个领域的学科。它研究如何利用计算机生成、处理和显示图像。计算机图形学在多个领域有广泛的应用,包括电影、游戏开发、虚拟现实等。 在计算机图形学中,最基本的是图像的生成和渲染。计算机图形学通过数学模型和算法来生成三维模型,并将其渲染成二维图像。这涉及到对光照、颜色、纹理等因素的建模和计算。通过计算机图形学的技术,我们可以在屏幕上展示出逼真的图像,使得人们可以感受到一种身临其境的视觉体验。 另外,在计算机图形学中,还有一些高级的技术,如计算机动画、虚拟现实等。计算机动画利用计算机图形学的原理和方法,将静态的图像进行快速连续地播放,从而形成动态的图像。虚拟现实则是利用计算机图形学的技术,模拟出一种虚拟的环境,使人们可以通过头戴式显示器等设备,身临其境地体验到虚拟环境中的视觉效果。 在图形学领域中,有很多经典的算法和技术,如光线追踪、多边形填充、抗锯齿等。计算机图形学的发展也受益于计算机硬件的不断升级,如显卡的发展,使得图形计算能力得到了大幅提升。 总结来说,现代计算机图形学是一个复杂而有趣的学科,它使用计算机生成、处理和显示图像,具有广泛的应用领域。通过计算机图形学的技术,我们可以创造出逼真的视觉效果,从而提升用户的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值