当前位置: 首页 > news >正文

dda算法画直线_计算机图形学三:直线光栅化的数值微分算法,中点Brensenham算法和三角形的光栅化...

6313fbf411f1e1723ec9fcd0fc278f93.png

直线与三角形的光栅化算法

在进入具体的直线光栅化以及三角形光栅化算法之前,我们首先需要知道光栅化是一个什么样的过程。简单来说光栅化的目的就是将想要展现的物体给真正现实到屏幕上的过程,因为我们的物体其实都是一个个顶点数据来表示的,如何表这些蕴含几何信息的数据转化为屏幕上的像素就是光栅化所考虑的东西。比如说一条直线,究竟该用哪些像素点去逼近它,一个三角形,又用哪些像素集合表示它,这都是光栅化的过程。本节主要讨论介绍两个直线光栅化和一个三角形光栅化算法。

1 屏幕像素的表示

68ef99917118651d7c0198439ea6279b.png

屏幕中的每一个像素点我们都用整数坐标进行表示,最大最小值与分辨率相对应,考虑到每个像素都有一定的面积,我们定义(x+0.5,y+0.5)为该(x,y)像素的中心,如图中黑圈所示。

2 直线光栅化算法

2.1 DDA数值微分算法

DDA算法是一个非常简单直观的算法。 首先当任何一条直线知道任意两点时都可以用

来表示,其中k代表斜率,如果
,那么它的主要行进方向就是x轴,即x轴的变化要比y轴快,相反如果如果
,那么它的主要行进方向就是y轴,即y轴的变化要比x轴快。如下图所示:

8013ca79ef12e5b546dd2f4835a4e477.png

我们分别就图上两种情况进行考虑(假设起点与终点给定(确定了直线方程),就像图中一样)

1 当

时,从起点开始画起每次x = x+1, y = y+k, 并将y四舍五入,得到新的x,y就是像素点应该画的地方

2 当

时,从起点开始画起每次y = y+1, x = x+1/k, 并将x四舍五入,得到新的x,y就是像素点应该画的地方

图中的两种情况的光栅化结果也已给出供参考。

2.2 中点Bresenham算法

我们首先规定想要光栅化的线段的起点

与终点
,则该直线方程可以用y = kx + b的形式来表示,定义
, 准备工作完成之后,接下来一起看看bresenham算法的具体过程!

中点Bresenham算法的思想其实也比较简单,我们在这里只给出

的情况,其它情况可以类推,除却起点与终点,我们每次的画点只会考虑右边或者右上的点两种情况(由斜率所决定的),因此我们只需要在这二者之间做出选择。那么该依据什么进行判断呢,给出如下两种情况,第一:

31eb7b31fa99055af586e2f2b3f53781.png

我们已经成功画出了前三个蓝色方格之后,所要考虑的便是第三个蓝色方格右边或者右上的橙色方格,此时我们取这两个橙色方格的中点,如图中圆圈符号所对应的那个点,倘若这个点在直线方程的下面,那么很明显我们应该选择右上的方格。

第二种情况:

e512037bba5774b036a06dca94edbb83.png

此时中点位于直线方程的上方,此时选择右边的橙色方格。

至此,如何判断两种方格选择的条件已很明显,就是确定中点与直线的位置关系,这里就可以使用到一开始定义的

的方程了。

显然,当f(x+1,y+0.5) > 0的时候中点在直线上方,当f(x+1,y+0.5) < 0的时候中点在直线下方 (其中x+1,y+0.5是为了表示两个橙色方格的中点,此时x,y为前一个确定的像素坐标)

伪代码如下:

e3e3f30d5e68591ab0b757daf5106651.png

其中的,some condition也就很明显的是

0a0807b122aa96ead690af8deffc70cb.png

目前为止,算法整体便已完成,但有一个问题是,我们每次都要进行一次F(x,y)的计算,倘若直线方程比较复杂,这是很消耗资源的(因为在底层可能是几百万次的重复调用)。因此一种改进方法便是利用增量算法。不难具体算出f(x,y)方程具体如下:

983607627775fe69d2550990c3fc41b6.png

观察可以得出

05dc362bbfa1447725bda9751ecfdfdb.png

那么算法只需要算出第一次的 f(x+1,y+0.5) ,之后的每次只需根据上述式子进行相应增量计算即可,如下:

995b7ccf1153d5b63bd12c687c90b57e.png

如果还有不解,不妨具体的取两个点推一边算法便可加深理解。 当然中点bresenham算法其实还在这之上进一步做了一步优化,因为第一个d其中存在浮点数0.5,所以将有关d的等式两边都乘以2,消除了该0.5的浮点,增加了计算效率。

3 三角形光栅化算法

有读者可能会疑问,为什么不讲四边形五边形的光栅化算法,偏偏要谈三角形呢,因为三角形是最基本的多边形,大部分的模型都是用一个个三角形面表示,且任意的其它多边形其实都可以转化成多个三角形的形式,因此三角形的光栅化可以说是图形学中最基础的部分了。那么该怎么去做呢?

71bf8db8189fb91a2a8779bdd294509a.png

其实有一个非常直观的做法,我们对屏幕中的每一个像素进行采样,如果这个像素点在三角形之中那么这个像素点就应该被采用!对,这其实就是该算法的做法。那么该如何去判断一个点在不在三角形内部呢,那么其中一种办法就是利用叉乘的性质了

7265679a1925af7177ebc4182f3e59a8.png

如图所示,我们事先知道想要光栅化的三角形的三个顶点P0,P1,P2,以及检测点Q。 只要分别计算

,如果三者同号则代表点P在三条线段的同一边,那么必然处于三角形内部,如果不同号则代表该点一定在三角形外部!

因此自然的,只需要遍历每一个点就可以得出三角形的光栅化结果了!当然我们还可以进一步的进行优化,因为显然并没有必要去测试屏幕中的每一个点,一个三角形面可能只占屏幕很小的部分,可以利用一个bouding box 包围住想要测试的三角形,只对该bounding box内的点进行采样测试,如下图:

c18d4947f0ccdcf1bbec734f924bb8aa.png

这样就可以得到很大的效率提升了!

(强烈推荐闫令琪大佬的计算机图形学,讲的很棒B站有,本系列笔记可算作为该课程的对应笔记,并且会额外加上虎书以及其它计算机图形学课程的一些补充内容)

Reference

[1] Fundamentals of Computer Graphics 4th

[2] GAMES101-现代计算机图形学入门-闫令琪

[3] 华中科技大学-计算机图形学-万琳教授

相关文章:

  • arraylist存放不同数据类型_C++基础知识篇:C++的数据类型
  • oracle 两行数据合并成一行_oracle10g 多行数据合并为一行 | 学步园
  • idea创建包怎么让包分层_ROS基础-创建工作空间和功能包
  • python更改当前路径_类中python中的当前目录路径已更改
  • 德卡t10社保卡类型_德卡T10型多合一读写器通过社保检测
  • qgis折点打断_arcgis在折点处打断并建立网络分析(最短路径等问题)
  • icmp回复报文_UDP/IP硬件协议栈设计(六):ICMP
  • druid监控页面 关闭_springboot开启druid连接池的监控|教程
  • 开环传递函数判断系统类型_第七章-离散系统(1-20)
  • 5脚12v继电器接线图解_门禁系统现场接线图,简单易懂,喜欢学习的不要错过...
  • 平行相似定理_初中数学相似模型合集解析——A及8字模型
  • 广东科技学院专插本c语言考卷_29个专业!广东科技学院2021年专升本招生专业公布...
  • 物理搬砖问题_DNF:红眼搬砖格蓝迪攻略,新人必看
  • python双向链表 du_python实现双向链表
  • python 计算两个经纬度的距离_使用经纬度和海拔(高程)计算两点之间的距离...
  • 0x05 Python数据分析,Anaconda八斩刀
  • canvas 五子棋游戏
  • Debian下无root权限使用Python访问Oracle
  • Iterator 和 for...of 循环
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • java小心机(3)| 浅析finalize()
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • php ci框架整合银盛支付
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 第十八天-企业应用架构模式-基本模式
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • ------- 计算机网络基础
  • 坑!为什么View.startAnimation不起作用?
  • 理解在java “”i=i++;”所发生的事情
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 一天一个设计模式之JS实现——适配器模式
  • No resource identifier found for attribute,RxJava之zip操作符
  • gunicorn工作原理
  • 关于Android全面屏虚拟导航栏的适配总结
  • 正则表达式-基础知识Review
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • # 飞书APP集成平台-数字化落地
  • #大学#套接字
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (三)Honghu Cloud云架构一定时调度平台
  • (推荐)叮当——中文语音对话机器人
  • (小白学Java)Java简介和基本配置
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .net 7 上传文件踩坑
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验