计算机图形学课设(含所有程序图文)
计算机图形学课程设计
《计算机图形学》课程设计报告学院:专业:班级:姓名:学号:指导教师:年11 月15 日一、课程设计报告内容说明:1 、直线:1.1 点生成直线利用for 循环,用pDC->SetPixel(int x,int y,RGB(a,b,c))像素函数画出直线。
1.2 DDA :根据直线的微分方程来产生直线,即dy/dx=△y/△x=(12y y -)/(12x x -)=k其中(1x ,1y )、(2x ,2y )是直线的两个端点坐标。
DDA 算法的原理是增量法,即使x 和y 同时以很小的步长增长,每次增长量与x 和y 的一阶导数成正比。
直线的一阶导数是与△x 和△y 成正比的函数。
可以将x 和y 各递增ε△x 和ε△y 来产生线,ε是很小的量。
从当前画线任意点的位置(i x ,i y )上分别递增两个增量ε△x 和ε△y ,就可以得到直线增长的下一个(1+i x ,1+i y )的坐标位置公式如下1+i x =ix +ε△x1+i y =i y +ε△y1.3 金刚石将圆分为20份,利用直线生成的MoveTo 和LineTo 函数,使每个点与其他点相连。
展示图形为:点生成直线、数值微分法画直线、金刚石 2、曲线2.1 直角坐标系:写出参数表达式后,利用MoveTo 和LineTo 函数,连接各点。
如:正弦曲线:参数方程如下 x_SIN=1000*t; y_SIN=1000*sin(t);极坐标系:写出参数表达式后,利用MoveTo 和LineTo 函数,连接各点。
如:四叶图:参数方程如下r_SIYE=5000*sin(2*t); x_SIYE=r_SIYE*cos(t); y_SIYE=r_SIYE*sin(t);2.2 以实际工作中应用较多的参数样条曲线为例:参数样条曲线定义:给定n+1个控制点Pi (i =0,1,2,…,n ),n 次B 样条曲线段的参数表达式为: 。
依次用线段连接控制点Pi (i =0,1,2,…,n )组成的多边形称为B 样条曲线控制多边形。
《计算机图形学》课件
光照模型与阴影生成算法的应用广泛,例如在游戏开发、虚拟现实和 电影制作等领域。
纹理映射算法
纹理映射算法用于将图像或纹理贴图映射到三维物体 的表面。
输标02入题
常用的纹理映射算法包括纹理坐标、纹理过滤和纹理 压缩等。
01
03
纹理映射算法的应用广泛,例如在游戏开发、虚拟现 实和数字艺术等领域。
04
工业设计
使用CAD等技术进行产品设计和原型制作 。
游戏开发
创建丰富的游戏场景和角色,提供沉浸式 的游戏体验。
科学可视化
将复杂数据以图形方式呈现,帮助人们理 解和分析数据。
虚拟现实与增强现实
构建虚拟环境,实现人机交互,增强现实 感知。
02
计算机图形学基础知识
图像与图形的关系
图像
由像素组成的二维或三维数据,通常 用于表示真实世界或模拟的视觉信息 。
全息投影技术
总结词
全息投影技术能够实现三维立体显示,为观众提供沉浸式的 观影体验。
详细描述
全息投影技术利用干涉和衍射原理,将三维物体以全息图像 的形式呈现出来,使观众能够从不同角度观察到物体的立体 形态。这种技术将为电影、游戏和其他娱乐领域带来革命性 的变化。
增强现实技术
总结词
增强现实技术能够将虚拟信息与现实世界相结合,提供更加丰富的交互体验。
HSL和HSV模型
基于色调、饱和度和亮度(或 明度)来描述颜色。
RGBA模型
在RGB基础上增加透明度通道 。
图像处理技术
滤波和锐化
通过改变图像的像素值 来减少噪声、突出边缘
或细节。
色彩调整
改变图像中颜色的分布 和强度,以达到特定的
视觉效果。
图像分割
计算机图形学ppt(共49张PPT)
应用领域
广泛应用于机械、电子、建筑、汽车等制造业领域。
计算机游戏设计与开发
游戏引擎
基于计算机图形学技术构建游戏引擎, 实现游戏场景、角色、特效等的渲染 和交互。
应用领域
广泛应用于娱乐、教育、军事模拟等 领域。
游戏设计
利用计算机图形学技术进行游戏关卡、 任务、角色等的设计,提高游戏的可 玩性和趣味性。
纹理映射与表面细节处理
纹理坐标
定义物体表面上的点与纹理图像上的点之间 的映射关系。
Mipmapping
使用多级渐远纹理来减少纹理采样时的走样 现象。
Bump Mapping
通过扰动表面法线来模拟表面凹凸不平的细 节。
Displacement Mapping
根据高度图调整顶点位置,实现更真实的表 面细节。
透明度与半透明处理
Alpha Blending
通过混合像素的颜色和背景颜 色来实现透明度效果。
Order-Independent Transparency
一种解决透明物体渲染顺序问 题的方法,可以实现正确的透 明效果叠加。
Depth Peeling
通过多次渲染场景,每次剥离 一层深度,来实现半透明物体 的正确渲染。
如中点画圆算法,利用圆 的八对称性,通过计算决 策参数来生成圆。
多边形的生成算法
如扫描线填充算法,通过 扫描多边形并计算交点来 生成多边形。
二维图形的变换与裁剪
二维图形的变换
包括平移(Translation)、旋转(Rotation)、 缩放(Scaling)等变换,可以通过变换矩阵来实 现。
二维图形的裁剪
后期制作
在影视制作后期,利用计算机图形学技术进行颜色校正、合成、剪 辑等处理,提高影片质量。
计算机图形学_完整版 ppt课件
输入设备
键盘、鼠标 按钮盒、旋钮 跟踪球、空间球 操作杆 触觉反馈设备 数据手套、数据衣 数字化仪 扫描仪 触摸板 光笔 ……
硬拷贝设备
打印机 喷墨 激光 ……
绘图仪 台式 大型滚动传送式 ……
图形硬件系统组成模块示意图:
或称图形坐标系、用户坐标系、全局坐标系 如在世界坐标系中进行装配
观察坐标系(viewing coordinate)
对场景进行观察所对应的坐标系 对象经变换到该场景的一个二维投影——投影变换
规范化坐标系(normalized coordinate)
可使图形软件与特定输出设备的坐标范围无关 坐标范围:-1~1,或0 ~ 1 等等
在场景中对物体移动、旋转、缩 放、扭曲等,或转换模型坐标系
3D→2D,并对观察区域进行裁 剪和缩放
一种伪变换,对窗口上的最终输 出进行移动、缩放等
三维几何变换
可用4×4矩阵操作统一表示二维和三维几何变换
缩放、旋转、 对称、错切等
平移
投影
整体缩放
基本变换:平移、旋转、缩放
复合变换:可由平移、旋转、缩放和其他变换的矩阵乘积 (合并)形成。
图元的绘制、显示过程
顶点 法向量、颜色、纹理… 像素
图元操作、像素操作 光栅化(扫描转换)
像素信息 帧缓存 显示器
调用底层函数,如 setPixel (x,y);将当 前像素颜色设定值存 入帧缓存的整数坐标 位置(x,y)处。
图元描述与操作
几何图元由一组顶点(Vertex)描述 这一组顶点可以是一个或是多个。每个顶点信息二维或 三维,使用 2~4 个坐标。顶点信息由位置坐标、颜色 值、法向量、纹理坐标等组成。
计算机图形学课程设计完本
1中文摘要本次课程设计采用OpenGL来完成。
OpenGL是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。
OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。
本次课程设计是在win7系统下VC++6.0中的win32环境中,通过使用OpenGL所提供的标准库函数,综合图形学里的坐标转换,投影变换,光照以及纹理等知识,实现一个简单的太阳系的运行状况。
该系统仅做演示使用,将只包括太阳,地球与月亮,并且不保证相关数据的设定准确性。
目录一、课程设计任务及要求 (1)二、需求分析 (1)三、系统设计 (1)四、详细设计 (3)4.1 初始化的设定 (3)4.2 光源的位置与观察位置的设定 (4)4.3 纹理映射的设置 (5)4.4 各星球球体的绘制 (7)4.5 星球公转轨道 (9)4.6 人机交互式的实现 (10)五、运行调试与分析讨论 (12)5.1 程序运行截图 (12)5.2 结果分析 (13)六、设计体会与小结 (14)七、参考文献 (16)一、课程设计任务及要求1.利用OpenGL创建太阳,地球,月亮三个球体。
2. 实现“月亮绕着地球转,地球绕着太阳转”。
3. 为太阳,地球,月亮附上不同的纹理。
4. 具有较好的动画效果,消除闪烁现象。
5. 其他功能的添加。
二、需求分析本次课程设计使用的编译软件为Visual C++ 6.0。
设计中通过调用OpenGL函数库以来完成太阳,月亮,地球的球体绘制与纹理的加载,通过矩阵的变换以实现星球的运动效果。
从而模拟出太阳系的运行效果动画。
在之后,加入星球的轨道轨迹,使得模拟系统3D效果更加明显。
并加入人机交互操作。
通过“q,w,e,s,a,d”键来调整观察视角,可以实现全方位对此系统进行观察,使系统具有一定的可操作性。
三、系统设计本次课题为:实现太阳系运行动画。
系统设计步骤为:1.太阳,地球,月亮三个球体的创建。
计算机图形学课设 含所有程序图文
计算机图形学课程设计报告系(院):计算机科学学院专业班级:信计11102 姓名:吴家兴学号: 201106262 指导教师:严圣华设计时间:2014.6.16 - 2014.6.26设计地点:10教机房(此处目录根据自己情况可以调整改动)一、课程设计目的 ................................................. 错误!未定义书签。
二、课程设计具体要求..................................... 错误!未定义书签。
三、需求分析与总体设计 ..................................... 错误!未定义书签。
四、详细设计与实现[含关键代码和实现界面] ... 错误!未定义书签。
五、小结......................................................................................... 错误!未定义书签。
一、课程设计目的计算机图形学课程设计是验证、巩固和补充课堂讲授的理论知识的必要环节,通过上机实验,培养学生的自学能力、动手能力、综合运用知识解决实际问题的能力。
要求学生运用计算机图形学理论与技术设计、编写、调试程序并撰写课程设计报告。
二、课程设计具体要求1.独立完成设计并撰写课程设计报告。
2.在规定时间将程序和设计报告用附件(信计111X班XXX 图形学课设报告.RAR)发送到274548837@,并上交纸质打印稿(A4纸10页左右)。
3. 课程设计报告内容包括:(1)列出设计者姓名及本人详细信息、所用开发工具;(2)程序的基本功能介绍;(3)程序实现步骤和关键算法的理论介绍;(4)关键源代码实现说明。
(不要打印全部源程序!)(5)程序运行界面截图(3幅左右)(6)课设总结和自我评价。
4.《计算机图形学》课程的知识结构体系:(1)课设为期两周:总学时为40学时,2学分(2)学生必须完成二维线画图元和二维填充图元两个大功能。
计算机图形学 课程设计
2、gluSphere(quadric, 0.45f, 40, 40)函数是在原点绘制图形,经过 glTranslatef* 和 glRotatef*平移和旋转可以随意改变球体位置:
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); // 将坐标系绕 X 轴旋转-90 度 glTranslatef(1.7f, 0.0f, 0.0f); // 将坐标系右移 1.7f
8、建立一个地球公转轨道,调用函数 glTranslatef*把球体平移一定距离,使其在自
4
己的轨道上运行。同时为了使月球跟随地球,glRotatef(fEarthOrbit , 0.0f, 1.0f, 0.0f); 将坐标系绕 Y 轴旋转地球公转的角度,控制月亮跟随地球,用函数 glTranslatef*平移使月 球轨道在地球周围而不与地球重叠。
5
参数代表要操作的目标,GL_PROJECTION 是对投影矩阵操作,GL_MODELVIEW 是对模型视景矩 阵操作,GL_TEXTURE 是对纹理矩阵进行随后的操作。 13、glutIdleFunc(void (*func)(void))在 glutIdleFunc(void (*func)(void))回调函数 中指定一个函数,如果不存在其他尚未完成的事件(例如,当事件循环处于空闲的时候), 就执行这个函数。这个回调函数接受一个函数指针作为它的唯一参数。如果向它传递 NULL(0),就相当于禁用这个函数。glutMainLoop 进入 GLUT 事件处理循环。在一个 GLUT 程 序中,这个例程被调用一次 。一旦被调用,这个程序将永远不会返回 无限循环。它将调用 必要的任何已注册的回调。程序最后调用这个函数,让程序循环执行下去,使运动继续下去。
9、OpenGl 把三维坐标中的球体绘制到而为坐标屏幕,绘制的顺序是按代码的顺序来进 行的。因此后绘制的物体会遮住先绘制的物体,既使后绘制的物体在先绘制的物体后面也是 一样,使用深度测试可以解决这个问题。使用方法是:以 GL_DEPTH_TEST 为参数调用 glEnable 函数,启动深度测试。在必要时(通常是每次绘制画面开始时)清空深度缓冲,即: glClear(GL_DEPTH_BUFFER_BIT) , 其 中 glClear(GL_COLOR_BUFFER_BIT) 与 glClear(GL_DEPTH_BUFFER_BIT) 可 以 合 并 写 为 glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT),且后者运行速度比前者快。
计算机图形学完整ppt课件
工业设计
利用计算机图形学进行产品设计、仿 真和可视化,提高设计效率和质量。
建筑设计
建筑师使用计算机图形学技术创建三 维模型,进行建筑设计和规划。
计算机图形学的相关学科
计算机科学
计算机图形学是计算机科学的一个重 要分支,涉及计算机算法、数据结构、 操作系统等方面的知识。
物理学
计算机图形学中的很多技术都借鉴了 物理学的原理,如光学、力学等,用 于实现逼真的渲染效果和物理模拟。
02
03
显示器
LCD、LED、OLED等,用 于呈现图形图像。
投影仪
将计算机生成的图像投影 到大屏幕上,用于会议、 教学等场合。
虚拟现实设备
如VR头盔,提供沉浸式的 3D图形体验。
图形输入设备
键盘和鼠标
最基本的图形输入设备,用于操 作图形界面和输入命令。
触摸屏
通过触摸操作输入图形指令,常 见于智能手机和平板电脑。
多边形裁剪算法
文字裁剪算法
判断一个多边形是否与另一个多边形相交, 如果相交则求出交集部分并保留。
针对文字的特殊性质,采用特殊的裁剪算法 进行处理,以保证文字的完整性和可读性。
05
光照模型与表面绘制
光照模型概述
光照模型是计算机图形学中用于模拟光线与物体表面交互的数学模型。
光照模型能够模拟光线在物体表面的反射、折射、阴影等效果,从而增强图形的真 实感。
二维纹理映射原理
根据物体表面的顶点坐标和纹理坐标,计算出每个像素点对应的纹 理坐标,从而确定像素点的颜色值。
二维纹理映射实现方法
使用OpenGL中的纹理映射函数,将纹理图像映射到物体表面。
三维纹理映射技术
三维纹理坐标
定义在三维空间中的坐标,表示纹理图像上的位置。
教学课件 《计算机图形学》
孔斯曲面。法国雷诺公司的贝赛尔(P.Bezier)也提出了Bezier曲
线和曲面,他们被称为计算机辅助几何设计的奠基人。
•
70年代是计算机图形学发展过程中一个重要的历史时
期,计算机图形技术的应用进入了实用化的阶段,交互式图形系
统在许多国家得到应用;许多新的更加完备的图形系统不断被研
制出来。除了在军事上和工业上的应用之外,计算机图形学还进
次使用了“计算机图形”(Computer Graphics)这
个术语。此论文指出交互式计算机图形学是一个
可行的、有用的研究领域,从而确立了计算机图
形学作为一个崭新的学科分支的独立地位。
•
1964年,孔斯(S.Coons)提出了用小块曲面片组合表
示自由曲面,使曲面片边界上达到任意高阶连续的理论方法,称
•
1.以大型机为基础的图形系统
•
2.以中型或小型机为基础的图形系统
•
3.以工作站为基础的图形系统
•
4.以微机为基础的图形系统
2.2 图形硬件设备
•2.2.1图形显示设备
•1.阴极射线管(CRT)
• 最大偏转角 • 余辉时间 • 刷新 • 刷新频率
• 2.彩色阴极射线管(彩色CRT)
• 电子束穿透法 • 荫罩法
• 常用概念:
• 图像刷新 • 行频、帧频 • 逐行扫描、隔行扫描 • 像素 • 分辨率 • 点距 • 显示速度 • 帧缓冲存储器(帧缓存、显示存储器) • 色彩与灰度等级 • 颜色查找表
• 6.液晶显示器(Liquid-Crystal Display)
• 可视角度 • 点距和分辨率
• 7.等离子显示器
•
6.科学计算可视化
第2章 图形系统
计算机图形学(C版)2PPT课件
#define FALSE 0 #define TRUE 1 edge-flag(polygon,color)
{勾画多边形的轮廓线;
边标志算法
for(每条与多边形相交的扫描线)
{ inside=FALSE; for(x=0;x<=xmax;x++) /*该扫描线上所有的像素*/ { if (像素已设置为边界值)inside取反; if(inside=TRUE)像素置为填充色; else 像素置为背景色;
P151例:用边填充算法填充
P3
P3
P4 P2
P5
P5
P4 P6
P2P3 P3P4 P4P5 P5P1 如果按其它顺序填充,会如何?
边填充算法
优点:
– 它适合具有帧缓存的图形显示系统 – 可按任意顺序处理多边形的边 – 仅访问与该边有交点的扫描线上右方的像素,
算法简单
有何缺点?
缺点
对复杂图形,每一像素可能被访问多次,输入/ 输出量大 –图形输出不能与扫描同步进行
6
1.5 1 3
105
2.5 1 2
104
5 804
7.5 -1 2
3.5 1 1
4
103
803
6.5 -1 1
4.5 1 0
3
102
802
5.5 -1 0
101
2
801
100
1
800
1 1.5
(1,6)
P150图
1
2.5 7.5 8(1,5),(2,5),(7,5)
(1,4),(2,4),(3,4),(6,4),(7,4)
}
}
}
优点:像素不被重复处理。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机图形学课程设计报告系(院):计算机科学学院专业班级:信计11102姓名:吴家兴学号:201106262指导教师:严圣华设计时间:2014.6.16 - 2014.6.26设计地点:10教机房(此处目录根据自己情况可以调整改动)一、课程设计目的 ................................................. 错误!未定义书签。
二、课程设计具体要求..................................... 错误!未定义书签。
三、需求分析与总体设计 ..................................... 错误!未定义书签。
四、详细设计与实现[含关键代码和实现界面] ... 错误!未定义书签。
五、小结......................................................................................... 错误!未定义书签。
一、课程设计目的计算机图形学课程设计是验证、巩固和补充课堂讲授的理论知识的必要环节,通过上机实验,培养学生的自学能力、动手能力、综合运用知识解决实际问题的能力。
要求学生运用计算机图形学理论与技术设计、编写、调试程序并撰写课程设计报告。
二、课程设计具体要求1.独立完成设计并撰写课程设计报告。
2.在规定时间将程序和设计报告用附件(信计111X班XXX 图形学课设报告.RAR)发送到274548837@,并上交纸质打印稿(A4纸10页左右)。
3. 课程设计报告内容包括:(1)列出设计者姓名及本人详细信息、所用开发工具;(2)程序的基本功能介绍;(3)程序实现步骤和关键算法的理论介绍;(4)关键源代码实现说明。
(不要打印全部源程序!)(5)程序运行界面截图(3幅左右)(6)课设总结和自我评价。
4.《计算机图形学》课程的知识结构体系:(1)课设为期两周:总学时为40学时,2学分(2)学生必须完成二维线画图元和二维填充图元两个大功能。
二维裁剪和二维图形变换至少实现两个内容。
总共不少于10个算法。
(3)程序应做到:通用性、交互性、界面友好性!三、需求分析与总体设计1、Bresenham 基本算法(含画圆与画线):过各行各列象素中心构造一组虚拟网格线。
按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。
设直线方程为:其中k=dy/dx 。
因为直线的起始点在象素中心,所以误差项d 的初值d0=0。
X 下标每增加1,d 的值相应递增直线的斜率值k ,即d =d +k 。
一旦d ≥1, 就把它减去1,这样保证d 在0、1之间。
当d ≥0.5时,最接近于当前象素的右上方象素( ) 当d<0.5时,更接近于右方象素( )。
为方便计算,令e =d-0.5,e 的初值为-0.5,增量为k 。
当e ≥0时,取当前象素(x i ,y i )的右上方象素( );而当e<0时,更接近于右方象素( )。
可以改用整数以避免除法。
3. 数值微分(DDA)法已知过端点 的直线段L :y=kx+b,直线斜率为 从x 的左端点开始,向x 右端点步进。
步长=1(个象素),计算相应的y 坐标y=kx+b ;取象素点(x, round(y))作为当前点的坐标4.中点画线法当前象素点为(x p , y p ) 。
下一个象素点为P 1 或P 2 。
设M=(x p +1, y p +0.5),为p 1与p 2之中点,Q 为理想直线与x=x p +1垂线的交点。
将Q 与M 的y 坐标进行比较。
当M 在Q 的下方,则P 2 应为下一个象素点; 当M 在Q 的上方,应取P 1为下一点。
构造判别式:d=F(M)=F(x p +1,y p +0.5)=a(x p +1)+b(y p +0.5)+c ,其中a=y 0-y 1, b=x 1-x 0, c=x 0y 1-x 1y 0。
当d<0,M 在L(Q 点)下方,取右上方P 2为下一个象素; 当d>0,M 在L(Q 点)上方,取右方P 1为下一个象素; 当d=0,选P 1或P 2均可,约定取P 1为下一个象素;但这样做,每一个象素的计算量是4个加法,两个乘法。
d 是x p , y p 的线性函数,因此可采用增量计算,提高运算效率。
若当前象素处于d ≥0情况,则取正右方象素P 1 (x p +1, y p), 要判下一个象素位置,应计算d 1=F(x p +2, y p +0.5)=a(x p +2)+b(y p +0.5)=d+a ; 增量为a 。
若d<0时,则取右上方象素P 2 (x p +1, y p +1)。
要判断再下一象素,则要计算 d 2= F(x p +2, y p +1.5)=a(x p +2)+b(y p +1.5)+c=d+a+b ;增量为a +b 。
5.几何变换(平移与旋转)以一条直线段为例,完成目标的平移、绕任一点旋ky x x k y y i i i i i +=-+=++)(1111,++i i y x i i y x ,1+11,++i i y x i i y x ,1+),(),,(111000y x P y x P 0x转。
7.多边形剪裁基本思想是一次用窗口的一条边裁剪多边形,窗口的一条边以及延长线构成裁剪线,改线把平面分成两个部分:可见一侧,不可见一侧。
用一条裁剪边多多边形进行裁剪,得到一个顶点序列,作为吓一条裁剪边处理过程的输入点。
对于每一条裁剪边,只是判断点在窗口的哪一测以及求线段与裁剪边的交点算法应随之改变。
仅用一条裁剪边时,逐次多边形裁剪框图8. 多边形填充算法分析:确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y值(ymin和ymax),从y=ymin 到 y=ymax, 每次用一条扫描进行填充。
对一条扫描线填充的过程可分为四个步骤: a.求交b.排序c.交点配对d.区间填色。
在CGraphics类中的FillPlogon函数中实现多边形的填充算法。
9.直线段裁剪10.圆的填充算法四、详细设计与实现[含各部分代码和实现界面]用户界面:1.Bresenham算法代码如下:void Bresenhamline(int x1, int y1, int x2, int y2,CDC *pDC){ //对于所有直线均按照从左至右的方向绘制int x,y,d,dx,dy,right,rightleft;if(x1>x2){int tempx,tempy;tempx=x1;x1=x2;x2=tempx;tempy=y1;y1=y2;y2=tempy;}//根据斜率的情况不同而绘制if(y1==y2){//斜率为0的情况for(x=x1;x<=x2;x++)pDC->SetPixel(x,y1,2);}else if(x1==x2){//直线为垂直的情况if(y1>y2){ //使直线按从下往上画int tempy=y1;y1=y2;y2=tempy;}for(y=y1;y<=y2;y++)pDC->SetPixel(x1,y,2);}else{dy=y2-y1;dx=x2-x1;if(abs(dy)==abs(dx)){////斜率为1或-1时x=x1;y=y1;if(dy<0){//斜率为1for(;y>=y2;y--){x++;pDC->SetPixel(x,y,2);}}//斜率为1else{//斜率为-1for(;y<=y2;y++){x++;pDC->SetPixel(x,y,2);}}//斜率为-1}else if(abs(dy)<abs(dx)){//斜率的绝对值小于1时if(dy>0&&dx>0){//斜率为正时right=-2*dy;rightleft=2*dx-2*dy;d=dx-2*dy;x=x1;y=y1;while(x<=x2){pDC->SetPixel(x,y,2);x++;if(d<0){y++;d=d+rightleft;}else{d=d+right;}}}//斜率为正时else {//斜率为负时right=2*dy;rightleft=2*dy-2*dx;d=2*dy-dx;x=x1;y=y1;while(x<=x2){pDC->SetPixel(x,y,2);x++;if(d<0){y++;d=d+rightleft;}else{d=d+right;}}}//斜率为负时}//斜率的绝对值小于1时else{////斜率的绝对值大于1时if(dy>0&&dx>0){//斜率为正时right=2*dx;rightleft=2*dx-2*dy;d=2*dx-dy;x=x1;y=y1;while(y<=y2){pDC->SetPixel(x,y,2);y++;if(d>=0){x++;d=d+rightleft;}else{d=d+right;}}}//斜率为正时else{//斜率为负时right=-2*dx; rightleft=-2*dx-2*dy; d=-2*dx-dy; x=x1;y=y1; while(y>=y2){pDC->SetPixel(x,y,2);y--; if(d<0){ x++;d=d+rightleft;}else{ d=d+right;}}}//斜率为负时}//斜率的绝对值大于1时}//斜率的所有情况}void CBresenhamView::OnDraw(CDC* pDC) {CBresenhamDoc* pDoc = GetDocument(); ASSERT_V ALID(pDoc);Bresenhamline(10,10,500,50,pDC);// TODO: add draw code for native data here }1) 新建工程文件2) 打开下resenhamView.cpp3) 在// CBresenhamView drawing 代码后添加以上代码。
4) 运行成功5) 更改绘制坐标Bresenhamline(10,10,500,50,pDC) 可以改变直线斜率,还能通过直线的连接绘制多边形。
如: 6) //绘制多边形 7) Bresenhamline(10,10,500,10,pDC); 8) Bresenhamline(10,10,10,100,pDC); 9)Bresenhamline(10,100,600,120,pDC); 10)Bresenhamline(500,10,600,120,pDC);11)2.数值微分(DDA)法DDA 画线法:void DDALine(CDC *pdc,int x0,int x1,inty0,int y1,int color){float k=1.0*(y1-y0)/(x1-x0); int x=0,int y=y0; for(x=0;x<=x1;x++) { pdc->SetPixel(x,y,color); y=y+k; } } void CMy3View::On2() { // TODO: Add your command handler code here int x0,y0,x1,y1,color; x0=111; y0=111; x1=138; y1=138; color=RGB(0,0,255); CClientDC dc(this);DDALine(&dc,x0,x1,y0,y1,color)Midpoint 中点画线法:void Midpoint_Line(CDC *pdc,int x0,int y0,int x1,int y1,int color) { int a,b,d,d1,d2,x,y; a=y0-y1,b=x1-x0,d=2*a+b; d1=2*a,d2=2*(a+b);x=x0,y=y0; pdc->SetPixel(x,y,color); while(x<x1) { if(d<0) { x++; y++; d+=d1; } else { x++; d+=d2; } pdc->SetPixel(x,y,color); } } void CMy2View::On1() { // TODO: Add your command handlercode here int x0,x1,y0,y1,color; x0=111; y0=111; x1=138; y1=138; color=RGB(255,0,0); CClientDC dc(this); Midpoint_Line(&dc,x0,y0,x1,y1,color);}bresenham 画圆源程序void Bresenhan_circle() ;intx,y=180,color=1,xcenter,ycenter;x=0; int d=3-2*180;while(x<y) { if(d<0){d=d+4*x+6;x=x+1;}else{d=d+4*(x-y)+10;x=x+1;y=y-1;}pdc->SetPixel(0+x,0+y,COLOR);pdc->SetPixel(0+x,0-y,COLOR);pdc->SetPixel(0-x,0+y,COLOR);pdc->SetPixel(0-x,0-y,COLOR);pdc->SetPixel(0+y,0+x,COLOR);pdc->SetPixel(0+y,0-x,COLOR);pdc->SetPixel(0-y,0+x,COLOR);pdc->SetPixel(0-y,0-x,COLOR);}几何变换1. 目标的平移的源程序 xa1=xa+dx; ya1=ya+dy; xb1=xb+dx; yb1=yb+dy;2. 绕任意点旋转的源程序xa1=cos(angle/57.1)*xa-sin(angle/57.1)*ya+x-x*cos(angle/57.1)+y*sin(angle/57.1);ya1=sin(angle/57.1)*xa+cos(angle/57.1)*ya+y-y*cos(angle/57.1)-x*sin(angle/57.1);xb1=cos(angle/57.1)*xb-sin(angle/57.1)*yb+x-x*cos(angle/57.1)+y*sin(angle/57.1);yb1=sin(angle/57.1)*xb+cos(angle/57.1)*yb+y-y*cos(angle/57.1)-x*sin(angle/57.1);多边形填充//在指定的pDC设备中,填充多边形bool CGraphics::FillPloyon(CDC* pDC) {if(PointCount < 3)return false;//若多边形小于三个点则返回int minX = Point[0].x , minY = Point[0].y;int maxX = Point[0].x , maxY = Point[0].y;for(int i=1;i<PointCount;i++){if(minX > Point[i].x)minX = Point[i].x;if(minY > Point[i].y)minY = Point[i].y;if(maxX < Point[i].x)maxX = Point[i].x;if(maxY < Point[i].y)maxY = Point[i].y;}//获取多边形中所有坐标点的最大值和最小值,作为扫描线循环的范围CUIntArray myArray;int x,y;for(y=minY;y<maxY;y++){//扫描线从minY开始到maxYfor(i=0;i<PointCount;i++){//对每条边进行循环CPoint PointCross;intbeforeI=BeforeIndex(i),afterI=AfterInd ex(i);//判断是否跟线段相交if(InterCross(Point[beforeI],Point [i],CPoint(minX,y),CPoint(maxX,y),Poin tCross)){//若是存在交点,则进行相应的判断,即判断x的坐标取两次、一次还是不取if(PointCross==Point[i]){if((Point[beforeI].y > PointCross.y) && (Point[afterI].y > PointCross.y)){myArray.Add(PointCross.x);myArray.Add(PointCross.x);//边顶点的y值大于交点的y值,x坐标取两次}elseif((Point[beforeI].y - PointCross.y) * (Point[afterI].y - PointCross.y) < 0)myArray.Add(PointCross.x); //边顶点的y值在交点的y值之间,即一个顶点的y值大于交点的y值,而另一个小于,相应的x坐标取一次elseif(PointCross.y==Point[afterI].y)myArray.Add(PointCross.x);}elseif(PointCross==Point[beforeI]){continue;}elsemyArray.Add(PointCross.x);//当交点不在线段的顶点时,x坐标只取一次}}int*scanLineX,num=myArray.GetSize();scanLineX = new int[num];for(i=0;i<num;i++)scanLineX[i]=myArray.GetAt(i);//获取扫描线x值,以构成填充区间myArray.RemoveAll();SortArray(scanLineX,num);//对scanLine(扫描线x坐标进行排序)for(i=0;i<num;i=i+2){if(i+1>=num)break;for(x=scanLineX[i];x<scanLineX[i+1 ];x++)//x值配对填充pDC->SetPixelV(CPoint(x,y),RGB(255 ,0,0));//将填充区间相应点的颜色设置成红色}Sleep(1);//CPU暂停1ms,以体现出多边形是以扫描线的方式,一条一条的填充的delete scanLineX;}return true;}多边形生成图裁剪图及填充图多边形裁剪bool CGraphics::CutRect(CRect rect) {CPoint rectPoint[4];rectPoint[0].x = rect.left;rectPoint[0].y = rect.top;rectPoint[1].x = rect.right;rectPoint[1].y = rect.top;rectPoint[3].x = rect.left;rectPoint[3].y = rect.bottom;rectPoint[2].x = rect.right;rectPoint[2].y = rect.bottom;//获取裁减矩形的四个点的坐标,第一个点为左上,第二个点为右上,第三个点为右下,第四个点为左下int i;CArray<CPoint,CPoint&> myArray;//裁减后,保存的多边形的依次各点的坐标for(intrectNum=0;rectNum<4;rectNum++){//对裁减矩形的四条边进行循环for(i=0;i<PointCount;i++){//对每条边进行循环CPoint PointCross;intbeforeI=BeforeIndex(i),afterI=AfterInd ex(i);int afterrectNum = ((rectNum == 3)?0:rectNum+1);//判断是否跟线段相交if(InterCross(Point[beforeI],Point [i],rectPoint[rectNum],rectPoint[after rectNum],PointCross)){if(PointCross==Point[i]){myArray.Add(Point[i]);//交点在线段上,直接添加点坐标在保存多边形的数组中}elseif(PointCross==Point[beforeI]){if(IsInSquareRgn(rect,Point[i],rec tNum))myArray.Add(Point[i]);//判断是否可视,若是,则添加点坐标}else{myArray.Add(PointCross);//跟线段相交,但交点不在顶点上,添加交点坐标if(IsInSquareRgn(rect,Point[i],rec tNum))myArray.Add(Point[i]);//判断是否可视,若是,则添加点坐标}}elseif(IsInSquareRgn(rect,Point[i],rec tNum))myArray.Add(Point[i]);//线段不相交,但需判断是否可视,若是,则添加点坐标}PointCount=myArray.GetSize();if(Point)delete Point;Point = new CPoint[PointCount];for(i=0;i<PointCount;i++)Point[i]=myArray.GetAt(i);//重新赋予点坐标的值myArray.RemoveAll();}return true;}直线段裁剪:(单独用的函数)#define LEFT 1#define RIGHT 2#define BOTTOM 4#define TOP 8#define XL 150#define XR 350#define YB 200#define YT 300#include <math.h>#include <graphics.h>#include <stdio.h>encode(x,y,code) float x,y;int *code;{int c=0;if(x<XL)c=c|LEFT;else if(x>XR)c=c|RIGHT;if(y<YB)c=c|BOTTOM;else if(y>YT)c=c|TOP;*code=c;return *code;}void M_lieCLip(float x1,float y1,float x2,float y2,float *x,float *y){int code1,code2,code;float t=1,xx,yy;encode(x1,y1,&code1) ;encode(x2,y2,&code2);if (code1==0) { *x=x1; *y=y1;return;}while(code1&code2==0){L1:xx=(x1+x2)/2;yy=(y1+y2)/2;encode(x,y,&code);if(abs((x2-xx)*(x2-xx)+(y2-yy)* (y2-yy))<t){*x=xx;*y=yy;return;}if(code&code1!=0){x2=xx;y2=yy;}else{x1=xx;y1=yy;} } }void main() {floatx1,y1,x2,y2,xx,yy,xxx,yyy,t; int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode," "); setcolor(4); line(XL,YT,XR,YT); line(XL,YB,XR,YB); line(XL,YT,XL,YB);line(XR,YT,XR,YB);x1=50;y1=150;x2=400;y2=300;setcolor(7);line(x1,y1,x2,y2);xx=0;yy=0;xxx=0;yyy=0;M_lieCLip(x1,y1,x2,y2,&xx,&yy); M_lieCLip(x2,y2,xx,yy,&xxx,&yyy ); setcolor(11); line(xx,yy,xxx,yyy); getch();closegraph();}圆的填充算法 #include "stdlib.h"#include "math.h" #include <gl/glut.h> //按坐标画点 void draw(GLint xCoord, GLint yCoord){ glBegin(GL_POINTS);//以点的形式 glVertex2i(xCoord, yCoord);//在(xCoord, yCoord )坐标下画点 glEnd();glFlush();//强制刷新}void Circle(GLint x,GLint y) { int a=abs(x);//将x 的绝对值赋给a int b=abs(y);//将y 的绝对值赋给bint c=a*-1;//使c=a 的相反数 int d=b*-1;//使d=b 的相反数 draw(x, y); draw(y, x); draw(-x, y); draw(y, -x);draw(x, -y); draw(-y, x);draw (-x, -y); draw(-y, -x);//按照圆的对称性以圆心为对称点将四个象限的圆周画出for(int i=c;i<=a;i++) {for(int j=d;j<=b;j++) {draw(i,j); }}//以a,b,c,d 为边界用点填充该圆}//主函数void BresenhamCircle(GLint r) {int d, d1, d2, direct;GLint x,y;x=0;y=r;d = 2*(1-r);while(y>=0){Circle(x,y);if(d < 0){d1 = 2* (d+ y) -1;if(d1 <=0)direct = 1;elsedirect = 2;}else{if( d > 0){d2 = 2*(d-x)-1;if(d2 <= 0)direct = 2;elsedirect = 3;}elsedirect = 2;}switch(direct){case 1:x++;d+=2*x + 1;break;case 2:x++; y--;d+=2*(x-y+1) + 1;break;case 3:y--;d+=-2*y + 1;break;}}}void RenderScene(void){BresenhamCircle(50);//主函数调用}//当窗口大小改变时由GLUT函数调用void ChangeSize(GLsizei width, GLsizei Height) {GLfloat aspectRatio;if (Height == 0){Height = 1;}glViewport(0, 0, width, Height);//指定视口矩形左下角glMatrixMode(GL_PROJECTION);//指定当前矩阵,对投影矩阵应用随后的矩阵操glLoadIdentity();// 装载单位矩阵aspectRatio = (GLfloat)width / (GLfloat) Height;if (width <= Height){glOrtho(-100.0, 100.0, -100.0 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);}else{glOrtho(-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);}glMatrixMode(GL_MODELVIEW);//指定当前矩阵,对模型视景矩阵堆栈应用随后的矩阵操作glLoadIdentity();// 装载单位矩阵}//主程序入口void main(void){glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置初始显示模式,指定单缓存窗口,指定RGB 颜色模式的窗口glutCreateWindow("圆");//创建窗口,窗口名称为“圆”glutDisplayFunc(RenderScene);//进行画图glutReshapeFunc(ChangeSize);//重画回调函数glutMainLoop();//进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环}指导老师意见:成绩: 教师签名:年月日。