计算机图形学实验_基本图素的生成算法和图形填充

合集下载

《计算机图形学》实验指导书

《计算机图形学》实验指导书

计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现DDA、中点画线算法和Bresenham画线算法 (24)实验二实现Bezier曲线 (25)实验三实现B样条曲线 (26)实验四实现多边形填充的边界标志算法 (27)实验五实现裁剪多边形的Cohen-Sutherland算法 (28)实验六二维图形的基本几何变换 (30)实验七画图软件的编制 (31)实验一实现DDA、中点画线算法和Bresenham画线算法【实验目的】1、掌握直线的多种生成算法;2、掌握二维图形显示原理。

【实验环境】VC++6.0/ BC【实验性质及学时】验证性实验,2学时,必做实验【实验内容】利用任意的一个实验环境,编制源程序,分别实现直线的三种生成算法,即数字微分法(DDA)、中点画线法以及Bresenham画线算法。

【实验原理】1、数字微分法(Digital Differential Analyzer,DDA)算法思想:基于直线的微分方程来生成直线。

ε=1/max(|△x|,|△y|)max(|△x|,|△y|)=|△x|,即|k|≤1 的情况:max(|△x|,|△y|)=|△y|,此时|k|≥1:2、中点画线法算法思想:每次在最大位移方向上走一步,另一方向是否走步取决于误差项的判断。

3、Bresenham画线算法算法思想:其基本思想同中点算法一样,即每次在最大位移方向上走一步,而另一个方向是否走步取决于误差项的判断。

【实验要求】1.上交源程序;2.上交实验报告,实验报告内容如下:(1) 实验名称(2) 实验目的(3) 算法实现的设计方法及程序流程图(4) 程序结果分析【分析与思考】(1) 上述所阐述的三个算法,其基本算法只能适用于直线的斜率(|K|<=1) 的情形,如何将上述算法进行推广,使其能够处理任意斜率的直线?(2) 计算机显示屏幕的坐标圆心在哪里,与我们平时的习惯有什么差异,如何协调二者?实验二 实现Bezier 曲线【实验目的】1、掌握Bezier 曲线的定义;2、能编程实现N 次Bezier 曲线的绘制与显示。

计算机图形学--填充

计算机图形学--填充

扫描线多边形填充算法扫描线多边形区域填充算法是按照扫描线顺序,计算扫描线与多边形的相交区间,再用要求的颜色显示这些去区间的像素(即完成填充)。

填充过程:1 求交:计算扫面线与多边形个边的交点。

2 排序: 把所有交点按x值地震顺序排序。

2 配对:两两配对,1,和2,3和4 等等。

每对交点代表扫面线与多边形的一个相交区间。

4 填充:把相交区间内的像素设置成多边形颜色。

相交顶点的数目确定:检查相交顶点的两条边的另外两个定点的y值。

按这两个y值中大于交点y值得个数是0,1,2来决定是取0,1或2个。

边界像素取舍:对扫描线与多边形的相交区间取左闭右开。

水平边界处理:水平边不参与求交计算,跳过。

相交:把多边形的所有边放在一个表中,处理每条扫描线是,按顺序从表中取出所有边,分别与扫面线求交。

改进:效率低,可只求与它相交的多边形的边进行求交运算。

算法思想及实现:活性边:与当前扫描线相交的边。

活性边表:把活性边按与扫描线线交点x坐标递增的顺序存放在一个链表中。

活性边的每个节点的内容:X ,X的变化量,Y的最大值,一个指针。

1 存放当前扫描线与边的交点坐标x值。

2 存放从当前扫描线到下一条扫描线间x的增量3 存放该边所交的最高扫面线号ymax;4 存放指向下一条边的指针。

算法的主要步骤:建立NET(new edge list)从最低扫面线开始到最高扫面线循环。

建立或调整AET(active edge list)按照AET总的接点顺序填充。

算法描述:算法描述:void polyfill (多边形polygon, 颜色color){for (各条扫描线i ){ 初始化新边表头指针NET [i];把ymin = i 的边放进边表NET [i];}y = 最低扫描线号;初始化活性边表AET为空;for (各条扫描线i ){ 把新边表NET[i]中的边结点用插入排序法插入AET表,使之按x坐标递增顺序排列;遍历AET表,把配对交点区间(左闭右开)上的象素(x,y),用drawpixel (x, y, color) 改写象素颜色值;遍历AET表,把y max= i +1的结点从AET表中删除,并把y max > i+1结点的x值递增D x;若允许多边形的边自相交,则用冒泡排序法对AET表重新排序;}} /* polyfill */。

计算机图形学 实验三 二维图形的区域填充

计算机图形学 实验三 二维图形的区域填充

西北农林科技大学实习报告学院名称:理学院专业班级:姓名:学号:课程:计算机图形学实验报告日期:第十四周实验三二维图形的区域填充一、实验目的1)加深对填充算法的理解,分析比较种子填充和边缘填充的差异。

2)掌握二维图形区域种子填充的原理和算法。

二、实验步骤1)对任意多边形的几何形状进行分析,选定比较合适的算法模型。

2)画出程序流程图;3)编写程序的源程序;4)编辑源程序并进行调试;5)进行特殊模式的运行测试,并结合情况进行调整。

三、实验内容用种子填充算法编写程序实现区域填充,并能在计算机上编译运行,正确地实现任意多边形边界的单色填充。

原理边界填充算法可以让用户首先勾画图的轮廓,选择填充颜色和填充模式,然后拾取内部点,系统就可以自动给图的内部涂上所需要的颜色和图案。

该算法的输入是种子点坐标 ( x , y )、填充色和边界颜色。

算法从( x , y )开始检测相邻位置是否是边界颜色,若不是,就用填充色着色,并检测其相邻位置。

该过程延续到已经检测完区域边界颜色范围内的所有像素为止。

使用栈结构来实现4-连通边界填充算法的算法步骤如下:(1)种子像素入栈。

(2)执行如下三步操作:1 栈顶像素出栈。

2 将出栈像素置成填充色。

3 检查出栈像素的4-邻接点,若其中某个像素不是边界色且未置成多边形色,则把该像素入栈。

(3)检查栈是否为空,若栈非空重复执行步骤(2),若栈为空则结束。

边界填充算法可以用于填充带有内孔的平面区域。

其缺点是把太多的像素压入堆栈,有些像素甚至会入栈多次,这样一方面降低了算法的效率,另一方面还要求很大的存储空间以实现栈结构。

将之改进,可构造沿扫描线填充水平像素段的4-连通边界填充算法,其算法步骤如下:(1)种子像素入栈。

(2)执行如下三步操作:1 栈顶元素出栈。

2 填充出栈元素所在扫描行的连续像素段,从出栈的像素开始沿扫描线向左和向右填充,直到遇到边界像素为止,即每出栈一个像素,就对包含该像素的整个扫描线区间进行填充,并且记录下此时扫描线区间的x坐标范围[ x1, x2 ]。

实验二:图形填充算法实验报告

实验二:图形填充算法实验报告

《计算机图形学》实验报告(实验二:图形填充算法)一、实验目的及要求用两种方法做图形的填充算法!二、理论基础1.边填充算法对于每一条扫描线和每条多边形的交点(x1,y1),将该扫描线上的交点右方的所有像素取补。

2.种子填充算法利用栈来实现种子填充算法。

种子像素入栈,当栈非空时重复执行如下步骤:将栈顶像素出栈,将出栈像素置成多边形色,按左,上,右,下顺序检查与出栈像素相邻的四个像素,若其中某个像素不再边界且未置成多边形,则把该像素入栈!三、算法设计与分析1、边填充算法void CEdge_mark_fillView::OnDraw(CDC* pDC){CEdge_mark_fillDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);int d[500][500]={0};int inside;int x,y;Bresenham(80,101,100,400,d);Bresenham(100,300,290,400,d);Bresenham(292,400,382,50,d);Bresenham(380,50,202,150,d);Bresenham(200,150,82,101,d);for(y=0;y<500;y++){inside=0;for(x=0;x<500;x++){if(d[x][y]==1)if(d[x+1][y]!=1){inside=!(inside);}if(inside!=0)pDC->SetPixel(x,y,12);}}}2、种子填充int x=299,y=51;COLORREF oldcolor;COLORREF newcolor;oldcolor=RGB(256,256,256);newcolor=RGB(123,123,123);pDC->MoveTo (40,40);pDC->LineTo (80,40);pDC->LineTo (70,80);pDC->LineTo (40,40);FloodFill(51,51,RGB(255,255,255),RGB(0,0,255));pDC->LineTo (40,40);void CMyView::FloodFill(int x,int y,COLORREF oldcolor,COLORREF newcolor) {CDC* pDC;pDC=GetDC();if(pDC->GetPixel(x,y)==oldcolor){pDC->SetPixel(x,y,newcolor);FloodFill(x,y-1,oldcolor,newcolor);FloodFill(x,y+1,oldcolor,newcolor);FloodFill(x-1,y,oldcolor,newcolor);FloodFill(x+1,y,oldcolor,newcolor);}四、程序调试及结果的分析1、2、四、实验心得及建议由于很多不会,所以这次没能按时当堂完成,下来花了不少时间才弄出来,第二种尤其比较麻烦,在同学的帮助下才做出来了。

计算机图形学的基本概念与算法

计算机图形学的基本概念与算法

计算机图形学的基本概念与算法计算机图形学是研究如何利用计算机生成、处理和显示图像的学科。

它在许多领域中都有广泛应用,例如电影制作、游戏开发、医学成像等。

本文将介绍计算机图形学的基本概念和算法,并分步详细列出相关内容。

一、基本概念1. 图像表示:计算机图形学中,图像通常使用像素(Pixel)来表示。

每个像素包含了图像上一个特定位置的颜色或灰度值。

2. 坐标系统:计算机图形学使用不同的坐标系统来表示图像的位置。

常见的坐标系统有笛卡尔坐标系、屏幕坐标系等。

3. 颜色模型:计算机图形学中常用的颜色模型有RGB模型(红、绿、蓝)和CMYK模型(青、品红、黄、黑)等。

RGB模型将颜色表示为三个分量的组合,而CMYK模型用于打印颜色。

4. 变换:变换是计算机图形学中常用的操作,包括平移、旋转、缩放和剪切等。

通过变换,可以改变图像的位置、大小和方向。

5. 插值:在计算机图形学中,插值是指通过已知的数据点来推测未知位置的值。

常见的插值方法有双线性插值和双三次插值等。

二、基本算法1. 线段生成算法:线段生成是图形学中最基本的操作之一。

常见的线段生成算法有DDA算法(Digital Differential Analyzer)和Bresenham算法。

DDA算法通过计算线段的斜率来生成线段上的像素,而Bresenham算法通过绘制画板上的一个像素来逐渐描绘出整条直线。

2. 多边形填充算法:多边形填充是将一个多边形内的区域用颜色填充的过程。

常见的多边形填充算法有扫描线算法和边界填充算法。

扫描线算法通过扫描多边形的每一条水平线,不断更新当前扫描线下方的活动边并进行填充。

边界填充算法从某点开始,向四个方向延伸,逐渐填充整个多边形。

3. 圆弧生成算法:生成圆弧是计算机图形学中常见的操作之一,常用于绘制圆形和曲线。

常见的圆弧生成算法有中点圆生成算法和Bresenham圆弧生成算法。

中点圆生成算法通过计算圆弧中的每个点与圆心的关系来生成圆弧上的像素,而Bresenham圆弧生成算法通过在八个特定的扫描区域内绘制圆弧上的像素。

计算机图形学的基本算法

计算机图形学的基本算法

计算机图形学的基本算法计算机图形学是研究如何利用计算机生成、处理和显示图像的学科。

图形学的基本算法涵盖了多个方面,包括图像绘制、几何变换、光照和渲染等。

以下将详细介绍计算机图形学的基本算法及其步骤。

1. 图像绘制算法:- 像素绘制算法:基于像素的图形绘制算法包括点绘制、线段绘制和曲线绘制。

例如,Bresenham线段算法可用于绘制直线。

- 多边形填充算法:多边形填充算法用于绘制封闭曲线图形的内部区域。

常见的算法包括扫描线填充算法和种子填充算法。

2. 几何变换算法:- 平移变换:平移变换算法用于将图像在平面上进行上下左右的平移操作。

- 旋转变换:旋转变换算法用于将图像按照一定的角度进行旋转。

- 缩放变换:缩放变换算法用于按照一定的比例对图像进行放大或缩小操作。

- 剪切变换:剪切变换算法用于按照一定的裁剪方式对图像进行剪切操作。

3. 光照和渲染算法:- 光照模型:光照模型用于模拟物体与光源之间的相互作用。

常见的光照模型有Lambert模型和Phong模型等。

- 阴影生成算法:阴影生成算法用于在渲染过程中生成逼真的阴影效果。

例如,阴影贴图和阴影体积等算法。

- 光线追踪算法:光线追踪算法通过模拟光线的路径和相互作用,实现逼真的光影效果。

常见的光线追踪算法包括递归光线追踪和路径追踪等。

4. 图像变换和滤波算法:- 傅里叶变换算法:傅里叶变换算法用于将图像从时域转换到频域进行分析和处理。

- 图像滤波算法:图像滤波算法用于对图像进行平滑、锐化、边缘检测等操作。

常见的滤波算法包括均值滤波、高斯滤波和Sobel算子等。

5. 空间曲线和曲面生成算法:- Bézier曲线和曲面算法:Bézier算法可用于生成平滑的曲线和曲面,包括一阶、二阶和三阶Bézier曲线算法。

- B样条曲线和曲面算法:B样条算法可用于生成具有更高自由度和弯曲度的曲线和曲面。

以上列举的是计算机图形学中的一些基本算法及其应用。

CG_实验2_基本图形元素(直线)生成算法的实现

CG_实验2_基本图形元素(直线)生成算法的实现

实验二基本图形元素(直线)生成算法的实现1.实验目的:理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。

2.实验内容:(1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;(2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告;(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

3.实验原理:示范代码原理参见教材直线光栅化一节中的DDA算法。

下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。

(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。

同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。

可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。

这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。

前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或是做其它事情呢?为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。

例如:glBegin(GL_POINTS);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.0f);glEnd();则这两个点将分别被画出来。

如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。

还可以指定更多的顶点,然后画出更复杂的图形。

另一方面,glBegin 支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN等,每种方式的大致效果见下图:图B-2 OpenGL几何图元类型(2)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。

计算机基本图形生成算法

计算机基本图形生成算法
给定圆心在原点,半径为整数R的圆,其方程为
x2 y2 R2
构造函数F(x,y)=x2+y2-R2。 对于圆上的点,有F(x,y)=0; 对于圆外的点,F(x,y)>0; 而对于圆内的点,F(x,y)<0。
31
y
Pu
PM
Pd
x
图5.13 中点Bresenham画圆的原理
中点Bresenham画圆
y
yi
k
19
改进的Bresenham算法
kd
k d
kd
k kd
图5.10 改进的Brensemham算法绘制直线的原理
改进的Bresenham算法——原理
xi1 yi1
xi
yi yi
1
1
(d 0.5) (d 0.5)
误差项的计算
d初=0, 每走一步:d=d+k
一旦y方向上走了一步,d=d-1
中点Bresenham画圆
判别式的初始值
d0 F ( x0 1, y0 0.5) F (1, R 0.5) 1 (R 0.5)2 R2 1.25 R
36
改进:用d-0.25代替d 此时有:
d d 2xi 3
d 0.25
d d 2(xi yi ) 5 d 0.25
yi-2
(xi 2)2 ( yi 0.5)2 R2
xi xi+1 xi+2
d2 ( xi 1 1)2 ( yi 0.5)2 R2 图5.14 d≤0的情况
( xi 1)2 2xi 3 ( yi 0.5)2 R2
d1 2xi 3
误差项的递推(d>0)
yi
P
yi-1
构造判别式:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学号 专业 姓名
实验日期 2018.11.27 教师签字 成绩
实验报告
【实验名称】 基本图素的生成算法和图形填充
【实验目的】
1、 通过实验,进一步理解和掌握DDA 和中点Bresenham 算法;
2、 掌握填充算法的基本原理;
【实验原理】
1.给定直线两端点A(xA,yA)和B(xB,yB),画出该直线。

(1)数值微分法(DDA 算法)
△x=x B – xA ,△y= y B - y A
11y y y x
x x i i i i ∆⋅+=∆⋅+=++εε
(2)中点Bresenham 画直线算法
1)输入直线的两端点A(xA,yA)和B(xB,yB)。

2)△x=x B – xA ,△y= y B - y A , e= -△x 、x=xA 、y=yA 。

3)绘制点(x,y)。

4)e 更新为e+2△y ,判断e 的符号。

若e>0,则(x,y)更新为(x+1,y+1),同时将
e 更新为e-2△x ;否则(x,y)更新为(x+1,y)。

5)当直线没有画完时,重复步骤3和4。

否则结束。

2.边缘填充算法
填充多边形时:逐边处理。

对每一条边,将该边的右方所有像素取补。

【实验内容】
1.用数值微分法(DDA法)或中点Bresenham算法绘制任意一条直线;(由
键盘输入直线的两端点坐标)
#define SHOW_CONSOLE
#include "graphics.h" // 引用ege图形库
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<cstdlib>
const int size_x=640,size_y=480;
const double eps =1e-6;
void DrawLine(int x0,int y0,int x1,int y1)
{
if(x0 > x1){
std::swap(x0,x1);
std::swap(y0,y1);
}
//printf("[%d %d,%d %d]\n",x0,y0,x1,y1);
cleardevice();
double dx = x1-x0,dy=y1-y0,k,change;
if(fabs(dx-0)<= eps){//dx == 0
change = fabs(1/(dy*1.0));
k=999;
}else{
k = dy/(dx*1.0);
2.任意画一个多边形,并用边(缘)填充算法进行填充。

(多边形的顶点坐标存放在数组中,坐标值由键盘输入)
#define SHOW_CONSOLE
#include "graphics.h" // 引用ege图形库
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<vector>
const int size_x=640,size_y=480;
const double eps =1e-6;
std::vector<std::pair<int,int>> pos;
void DrawLine(int x0,int y0,int x1,int y1)
{
if(x0 > x1){
std::swap(x0,x1);
std::swap(y0,y1);
}
//printf("[%d %d,%d %d]\n",x0,y0,x1,y1);
double dx = x1-x0,dy=y1-y0,k,change;
if(fabs(dx-0)<= eps){//dx == 0
change = fabs(1/(dy*1.0));
k=999;
}else{
【小结或讨论】
因为是第一次实验,所以实验题目并不难。

但我依然做了比较长的时间,主要困难在于环境的配置。

一开始打算就python写,但在写到第二个题目的时候,python下的OpenGL库的glgetpixel函数会有很奇怪的问题,网上关于这个的资料也少,尝试了很久还是无法解决。

后来在c++环境下试着用OpenGL,还是这个函数出了问题,而且问题还和python下的问题不一样。

最后没有办法,只好使用Ege来完成实验。

Ege就是一个进化版的graphics.h ,没有了平台的限制。

但在写的时候依然遇到了问题,就是Ege默认是没有控制台的,导致无法完成实验要求。

最后终于在原码中看到了一行
终于在经过一系列波折之后总算配好了环境,成功完成了实验。

相关文档
最新文档