在VC++6.0中实现直线的扫描转换算法
基本图形生成算法(基于VC++6.0实现)

仲恺农业工程学院实验报告纸计算科学学院(院、系)信计082 班计算机图形学课实验一基本图形生成算法一、实验目的与要求:1. 掌握中点Bresenhanm绘制直线的原理2. 设计中点Bresenhanm算法3. 掌握八分法中点Bresenhanm算法绘制圆的原理4. 设计八分法绘制圆的中点Bresenhanm算法5. 掌握绘制1/4椭圆弧的上半部分和下半部分的中点Bresenhanm算法原理6. 掌握下半部分椭圆偏差判别式的初始值计算方法7.设计顺时针四分法绘制椭圆的中点Bresenhanm算法二、实验描述:1. 使用中点Bresenhanm算法绘制斜率为01≤≤的直线。
k2. 使用中点Bresenhanm算法绘制圆心位于屏幕客户区中心的圆。
3. 使用中点Bresenhanm算法绘制圆心位于屏幕中心的椭圆。
三、实验结果:1.打开VC++6.0程序;2.创建一个MFC工程,命名为exper1;选择单文档和作为静态的DLL,然后完成创建MFC工程;3.在ResourceView工作区窗口插入三个Dialog,第一个对话框作为画直线时用户输入起点坐标和终点坐标使用,第二个对话框作为画圆时用户输入所要画圆的半径使用,第三个对话框作为画椭圆时用户输入所要画椭圆的长半径和短半径使用;4.通过右键点击对话框选择建立类向导,因为本对话框是新建对话框还没有建立类向导,在此要新建一个line类,如下图所示,按照此方法将其他的两个对话框建立类向导分别为画圆建立Round类,画椭圆,建立Ellips类;5.完成类得建立后,对该对话框中的输入框进行添加变量与其关联,具体步骤如下图所示,按照此方法将所有的对话框中的输入框进行变量添加;6.打开Menu菜单中的选项,新建一个画图菜单,在画图菜单中新建直线、圆与椭圆子菜单,新建方法点击空白方框处右键选择属性,添加标明即可;7.点击子菜单,这里以直线为例,点击右键选择“建立类向导”,因为此时的直线的ID为“ID_1”,所以我们选择ID_1,类名选择刚刚建立的line类,按照下图中的方法,点击OK后向导既建立完成,建立完成后的图如下所示;8.在Class视图框中就会出现刚刚建立的line类、Round类和Ellips类,如下图,在CExper1View类中添加头文件;#include "line.h"#include "Round.h"#include "Ellips.h"9.在CExper1View类中添加下图中的变量m_stp记录输入的画直线的起点坐标,m_endp记录输入的画直线的终点坐标,m_x记录圆和椭圆的长半径(x轴的半径),m_y记录圆和椭圆的短半径(y轴的半径),因为圆的长半径和短相等,而由于我们这里画圆的方法完全采用画椭圆的方法,因此这里也需要长半径和短半径的长度,temp记录工程所要画的图形,在此定义当temp=1时为画直线,当temp=2时为画圆(椭圆);10.在OnDraw方法中写入以下代码,当temp=1时为画直线的代码,当temp=2时为画圆(椭圆)的代码,;11.分别对On1、On2、On3方法赋予实际的操作,主要是传值操作。
实验1 直线的扫描转换2003

实验1 直线的扫描转换一、实验要求基本要求1、用直线DDA算法实现任何斜率、任何方向直线的绘制。
2、用直线Bresenham算法实现│m│<1,任何方向直线的绘制。
提高要求1、用直线Bresenham算法实现任何斜率、任何方向直线的绘制。
2、用你编制的画线函数,实现虚线的绘制。
二、实验报告对下列内容逐项填写,适当添加空白页。
1.算法思想DDA算法原理:设过端点P0(x0,y0)、P1(x1,y1)的直线段为L(P0,P1),则直线段L的斜率为k=(y1-y0)/(x1-x0)。
要在显示器显示L,必须确定最佳逼近L 的像素集合。
我们从L的起点P0的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个象素),用L的直线方程y=kx+b计算相应的y坐标,并取象素点(x,round(y))作为当前点的坐标。
因为:y i+1= kx i+1+b= k1x i+b+k∆x=y i+k∆x所以,当∆x =1; y i+1= y i+k。
也就是说,当x每递增1,y递增k(即直线斜率)。
Bresenham算法原理:过各行各列象素中心构造一组虚拟网格线。
按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列象素中与此交点最近的象素。
该算法的巧妙之处在于采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求象素。
2.程序流程图Bresenham流程图3.源程序清单和结果DDA算法int x;float x0, y0, x1,y1, dx, dy, y, k;x0=10 ; x1=150 ;y0=20 ; y1=300 ;dx= x1-x0, dy=y1-y0;k=dy/dx, y=y0;for (x=(int)x0; x<=(int)x1; x++){ pDC->SetPixel(x, int(y+k), RGB(0,0,0));y=y+k;}Bresenham算法int x0, y0, x1,y1, dx,dy,dxx,dyy,e,y,x;x0=50 ; x1=260 ; y0=90 ; y1=600 ;dx=x1-x0;dy=y1-y0; dxx=dx+dx;dyy=dy+dy;e=dyy-dx;y=y0;for(x=x0;x<=x1;x++){ pDC->SetPixel(x,y,RGB(0,0,0));if(e>=0){ y=y++,e=e-dxx;}e=e+dyy;}4.实验总结两个算法有相似之处,注意程序的编写。
《计算机图形学》实验指导书

计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现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 曲线的绘制与显示。
图形学第3章 基本图形的扫描转换VC绘图函数孔令德编.ppt

此时中点Bresenham算法要从 (0,R)到(
)顺时针确定最佳逼近于该段圆弧的像素点集。
中点Bresenham算法的原理简化为:x方 向上每次加1,y方向上减不减1取决于中点 偏假差定判圆别当式前的点值是。P(xi,yi),下一点只能在 Pu(x i+1,y i)和Pd(x i+1,yi-1)中选 取,如图3-7所示。Pu和Pd的中点为M(x i+ 1,y i-0.5)显然,若M点在理想圆弧的下方, 则Pu点离圆弧近,点亮Pu;否则应点亮Pd。
A(0,b)
Pu Pd
Ⅰ Ⅱ
Pl Pr
B(a,0)
图3-12椭圆中点Bresenham算法原理
先考虑图3-12所示部分Ⅰ的AC段椭圆
弧。此时中Bresenham画椭圆算法要从
A(0,b)到(
,
)顺时针
确a定2 顺/ 时a针2 确b定2 最b佳2 逼/ 近a 2于该b段2 椭圆弧的
像素点集。
由于x方向为主位移方向,假定当前点
别式 3.3.3 上半部分Ⅰ的递推公式 3.3.4 构造Ⅱ中点偏差判别式 3.3.5 下半部分Ⅱ的递推公式
本节主要讲解顺时针绘制1/4椭圆的中 点Bresenham算法原理。
理想椭圆
y
F(x,y)>0
F(x,y) =0
x
F(x,y) <0
图3-9 椭圆的扫描转换
3.3.1 原理
圆心在原点、长半轴为a、短半轴为 b的椭圆方程的隐函数表达式为:
本节主要讲解仅包含加减操作的顺时针
绘制1/8圆的中点Bresenham算法原理。
理想圆
y
F(x,y)>0
F(x,y)=0
x F(x,y)<0
计算机图形学总复习

第一章:(蓝色字体为部分答案)●计算机图形学的定义?计算机图形学是研究通过计算机将数据转换为图形,并在专门显示设备上显示的原理、方法和技术的学科。
●计算机图形学常见的应用领域有哪些?(应用领域的标题)●计算机图形学的相关学科有哪些?和计算机图形学互逆的学科是?●CRT中为什么需要刷新?刷新频率是什么?由于荧光物质存在余晖时间,为了让荧光物质保持一个稳定的亮度值,电子束必须不断的重复描绘出原来的图形,这个过程叫做刷新刷新频率:每秒钟重绘屏幕的次数(次/秒、HZ)●彩色CRT和单色CRT的区别:⏹在荧光屏的内表面安装一个影孔板,用于精确定位像素的位置⏹CRT屏幕内部涂有很多组呈三角形的荧光粉,每一组由三个荧光点,三色荧光点由红、绿、蓝三基色组成(一组荧光点对应一个像素)⏹三支电子枪, 分别与三基色相对应●光栅扫描显示器中帧缓存是什么?位面是什么?⏹存储用于刷新的图像信息。
也就是存储屏幕上像素的颜色值。
⏹帧缓存的单位是位面。
⏹光栅扫描显示器屏幕上有多少个像素,该显示器的帧缓存的每个位面就有多少个一位存储器●1024×1024像素组成的24位真彩色光栅扫描显示器所需要的最小帧缓存是多少?第二章●什么是CDC?在微软基类库MFC中,CDC类是定义设备上下文对象的基类,所有绘图函数都在CDC基类中定义。
⏹简述CDC的4个派生类的名称,以及作用CClientDC类:显示器客户区设备上下文类CClientDC只能在窗口的客户区(不包括边框、标题栏、菜单栏以及状态栏的空白区域)进行绘图CMetaFileDCCMetaFileDC封装了在一个Windows图元文件中绘图的方法CPaintDC类该类一般用在响应WM_PAINT消息的成员函数OnPaint()中使用CWindowDC类整个窗口区域的显示器设备上下文类,包括客户区和非客户区(即窗口的边框、标题栏、菜单栏以及状态栏)⏹什么是映射模式?映射模式定义了Windows如何将绘图函数中指定的逻辑坐标映射为设备坐标输出到显示器或者打印机上。
直线的扫描转换(2)

4
DDA算法中斜率的值
5
DDA算法代码(当|k|<1)
void DDALine(int x0,int y0,int x1,int y1,int color) { int x; float dx, dy, y, k; dx = x1-x0; dy=y1-y0; k=dy/dx ; y=y0; for (x=x0; x<=x1; x++) { putpixel (x,(int)(y+0.5), color); y=y+k; } }
2
增量算法
增量算法:在一个迭代算法中,如果每一步 的x、y值是用前一步的值加上一个增量来获 得,则称为增量算法。
3
直线的扫描转换
直线的扫描转换的任务
确定最佳逼近于该直线的一组象素
按扫描线顺序,对这些象素进行写操作 直线的扫描转换的方法
数值微分(DDA)算法 中点画线法 Bresenham画线算法
12
中点画线算法原理
通过M的位置来确定下一个像素点。
M在直线的上方,取(xi +1 ,yi) 为下一像素点
M在直线的下方,取(xi +1 ,yi+1)为 下一像素点
13
问题:
计算机怎样知道M点和直线的位置关系? 直线方程: 将平面 分为了三个区域: y − kx − b = 0 F ( x, y ) =
此时,M点在直线下方,应取(xi+1,yi)为下一像素 点,再下一个点可能取(xi+2,yi+1)或(xi+2,yi),这 两个点的中点为(xi +2,yi+0.5),则:
di +1 = F ( xi + 2, yi + 0.5) = yi + 0.5 − k ( xi + 2) − b = yi + 0.5 − k ( xi + 1) − k − b = yi + 0.5 − k ( xi + 1) − b − k = di − k
直线扫描转换-中点算法

直线扫描转换-中点算法直线扫描转换-中点算法采⽤增量思想的DDA算法,直观、易实现,每计算⼀个象素坐标,只需计算⼀个加法。
(1)改进效率。
这个算法每步只做⼀个加法,能否再提⾼效率?⼀般情况下k与y都是⼩数,⽽且每⼀步运算都要对y进⾏四舍五⼊后取整。
唯⼀改进的途径是把浮点运算变成整数加法!(2)第⼆个思路是从直线⽅程类型做⽂章⽽直线的⽅程有许多类型,如两点式、⼀般式等。
如⽤其它的直线⽅程来表⽰这条直线会不会有出⼈意料的效果?中点画线法F(x,y) =0 直线的⼀般式⽅程:Ax+By+C=0其中A=Y1-Y2B=X2-X1C=X1Y2-X2Y1对于直线上的点: F(x,y)=0对于直线上⽅的点: F(x,y)>>0对于直线下⽅的点: F(x,y)<0每次在最⼤位移⽅向上⾛⼀步,⽽另⼀个⽅向是⾛步还是不⾛步要取决于中点误差项的判断.假定:0≤|k|≤1。
因此,每次在x⽅向上加1,y⽅向上加1或不变需要判断。
设U点为(x i+1,y i+1),D为(x i+1,y i),M(x i+1,y i+0.5)当M在Q的下⽅,则u 离直线近,应为下⼀个象素点, 当M在Q的上⽅,应取d 为下⼀点.如何判断Q在M的上⽅还是下⽅?把M代⼊理想直线⽅程:d i=A(x i+1)+B(y i+0.5)+C当d<0时,M在Q下⽅,取U当d>0时,M在Q上⽅,取D当d=0时,M在Q上,取UD均可(⼀般取D)⽤增量计算提⾼运算效率d0=A+0.5Bd1=d0+A+B d0<0d1=d0+A d0>=0y=y+1 d<0y=y d>=0可以⽤2d代替d来摆脱浮点运算,写出仅包含整数运算的算法。
当-1<k<0时的情况推导过程如下:第⼆个点应该是(5,0)结论如下: d0=-A+0.5Bd1=d0-A+B d0<0d1=d0-A d0>=0也可以⽤2d来摆脱浮点运算当1<k时的情况推导过程如下:注意:倒置后上下位置发⽣变化,因此x的取值和d的后续取值都发⽣变化结论如下: d0=0.5A+Bd1=d0+A+B d0>0d1=d0+B d0<=0x=x d<=0x=x+1 d>0也可以⽤2d来摆脱浮点运算当k<-1时的情况推导过程如下:下⾯的坐标应该是(3,0),从y0开始减。
直线段的扫描转换

Exp - Uni versity实验报告注:1、实验报告的内容:一、实验目的;二、实验原理;三、实验步骤;四、实验结果;五、讨论分析(完成指定的思考题和作业题);六、改进实验建议。
2 、各专业可在满足学校对实验教学基本要求的前提下,根据专业特点自行设计实验报告的格式,所设计的实验报告在使用前需交实践教学管理科备案。
则有:若d=0, M与Q点重合,Pu和Pd都合适,约定取Pd故有:误差项递推:(1)当d<0时,下一个候选点为(xi+1, yi+1),再下两个候选点为(xi+2, yi+1)(xi+2, yi+2),他们的中点为(xi+2, yi+ ,故有:此时,d的增量为1 —k(2)当d>0时,下一个候选点为(xi+1, yi),再下两个候选点为(xi+2, yi)和(xi+2, yi+1),他们的中点为(xi+2, yi+ ,故有:此时,d的增量为一k。
初始值d的计算:但此时算法中仍然包含了浮点数运算,由于这里我们仅使用了判别式d的符号,所以可以用2d A x代替d来摆脱小数。
用2d A x代替d ,令D= 2d A x贝U:3、改进Bresenham算法基本原理:假定直线段的O w k<1如下图所示,过各行、各列像素中心构造一组虚拟网格线,按直线起点到终点的顺序计算直线与各垂直网格线的交点,交点与网格线的误差值为d o当d>时,直线更接近于像素点(x+1, y+1),当d<时,更接近于(x+1,y);当d= 时,约定取(x+1, y) o图5-4改进的Brensemhan算法绘制直线的原理误差项d的初始值为0,每走一步有d=d+k, —旦y方向上走了一步,就要把d减去1。
即有:改进1 :令e=d—改进2:用E=2e^x来替换e八、算法流程1、DDA算法(数值微分法)适用于任意斜率的直线以下算法流程仅适用于斜率为0<k<1的直线对于斜率为k>1的直线,只需交换x、y的地位即可。
扫描转换直线段的中点算法

扫描转换直线段的中点算法
扫描转换直线段的中点算法是一种常用于计算机图形学中的算法。
该算法基于扫描线的概念,将直线段转换为一系列离散点,并计算这些点的中点,从而得到直线段的中点。
具体来说,扫描转换直线段的中点算法的步骤包括:
1. 将直线段按照从左到右的顺序排列,并计算出直线段的斜率。
2. 从直线段的起点开始,以固定步长(如每个像素点)沿着直线段向右扫描。
3. 在每个扫描线上,计算出直线段与该扫描线的交点,并将该点作为离散点。
4. 对于每个扫描线上的离散点,计算它与上一条扫描线上的离散点的中点,并将该中点作为直线段上的一个中点。
5. 重复第2-4步,直到扫描到直线段的终点。
扫描转换直线段的中点算法可以用于绘制直线段、计算直线段的长度和角度等应用。
此外,该算法还可以通过插值等技术扩展到曲线和曲面的计算中。
- 1 -。
直线段的扫描转换算法

直线段的扫描转换算法数值微分(DDA)法设过端点P0(x0 ,y0)、P1(x1 ,y1)的直线段为L(P0 ,P1),那么直线段L的斜率L的起点P的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个象素),用L的直线方程y=kx+b计算相应的y坐标,并取象素点(x,round(y))作为当前点的坐标。
因为:y= kx i+1+bi+1= k1x i+b+k x= y i+k x因此,当x =1; y i+1 = y i+k。
也确实是说,当x每递增1,y递增k(即直线斜率)。
依照那个原理,咱们能够写出DDA画线算法程序。
DDA画线算法程序void DDALine(int x0,int y0,int x1,int y1,int color){ int x;float dx, dy, y, k;dx = x1-x0; dy=y1-y0;k=dy/dx,;y=y0;for (x=x0;x< x1;x++){ drawpixel (x, int(y+, color);y=y+k;}}注意:咱们那个地址用整型变量color表示象素的颜色和灰度。
举例:用DDA方式扫描转换连接两点P0(0,0)和P1(5,2)的直线段。
x int(y+ y+0 0 01 0 +2 1 +3 1 +4 2 + 图2.1.1 直线段的扫描转换注意:上述分析的算法仅适用于|k| ≤1的情形。
在这种情形下,x每增加1,y最多增加1。
当|k| 1时,必需把x,y地位互换,y每增加1,x相应增加1/k。
在那个算法中,y与k必需用浮点数表示,而且每一步都要对y进行四舍五入后取整,这使得它无益于硬件实现。
中点画线法假定直线斜率k在0~1之间,当前象素点为(x p,y p),那么下一个象素点有两种可选择点P1(x p+1,y p)或P2(x p+1,y p+1)。
假设P1与P2的中点(x p+1,y p+)称为M,Q为理想直线与x=x p+1垂线的交点。
基本光栅图形算法--直线的扫描转换(I)

2006-2007-2:CG:SCUEC
生成直线算法的基本要求(2-1)
• 能不能直接用数学公式画直线段?
void DirectLine(int x0, int y0, int x1, int y1, int color) int x; float dx, dy, b, k; dx = x1-x0, dy=y1-y0; k=dy/dx, b=y0-k*x0; A(x0,y0) for (x=x0; xx1, x++) DrawPixel (x, int(k*x+b), color);
2006-2007-2:CG:SCUEC
else { // Y方向长,斜率>1 Length = abs(Round(ye)-Round(ys)); Flag=0; iy = Round(ys); //初始Y点 idy = sign(dy); //Y方向单位增量 x= xs+dx/dy*((float)(iy)-ys); //初始X点修正 dx=dx/fabs(dy); //X方向斜率增量 } if (Flag) { //X方向单位增量 for (n=0; n<= Length; n++) { //X方向插补过程 DrawPixel(ix, Round(y), color); ix+=idx; y+=dy; } //End of for } //End of if else { //Y方向斜率增量 for (n=0; n<= Length; n++) { //Y方向插补过程 DrawPixel (Round(x), iy, color); iy+=idy; x+=dx; } //End of for } //End of else } //Finish
用中点算法扫描转换直线段

用中点算法扫描转换直线段电信001 李理0052011一.算法教材里已有现成的算法,只要把其中的算法修改一下就行了。
应该修改的第一点是:在教材中,是根据平时的习惯将左下角左为坐标原点,而在PC 机中左上角为坐标原点。
因此在实际程序中,计算(x,y)时仍照教材,只是将putpixel(x,y,color) 必成putpixel(x,HEIGHT-y,color)就行了,其中变量HEIGHT为屏幕的最大分辨率,可用C 系统提供的getmaxy 函数得到,它的原型为:int far getmaxy(void);第二个问题是关于怎么按斜率的来分类。
我在这里将它分为了6类:即斜率为(0,∞),(0,1),(1,+∞),(-1,0),(-∞,-1)。
将0和∞单独处理是因为这样速度会快一点(也许感觉不到)。
斜率的判断,最初的考虑是用(y1-y0)/(x1-x0),但因为在定义时这些变量都是整型,所以不能正确判断。
另外考虑到教材的算法是假定起点的横坐标小于终点的横坐标的,所以在一开始就将横坐标小的作为起点。
(换序来实现)这样,只要y1>y0就说明斜率大于0,而再加上(y1-y0)<(x1=x0)这个条件就说明它满足教材算法的条件了。
下面要解决的问题是斜率在(1,+∞)的算法了。
我们选y轴为计长方向(每次加一),可推出:xi+1,r=x i,r, 当d i< 0xi+1,r=x i,r+1,当d i>=0d i+1=d i+2Δx, d i< 0d i+1=d i+2(Δx+Δy), d i>=0最后的问题就是斜率为(-1,0)和(-∞,-1)的情况。
当然也可以另写类似的算法,不过我们可以利用已有的(0,1)的算法和(1,+∞)的算法,只要作一个变换:将(x1,y1)作直线y=y0的对称点,即用(x0,y0),(x1,2*y0-y1) 这两点满足第一种条件,在画点时只要再用(2*y0-y)代替y就行了。
使用OpenGL编程实现Bresenham直线扫描转换算法

实验要求:学习Visual C++ 6.0 集成编程环境的使用,OpenGL编程环境的设置,OpenGL语法及基本函数的使用等基础知识,并编程实现Bresenham直线扫描转换算法,得出相应的输出图形。
源程序:#include<GL/glut.h>void k1() //0<k<1{glClear(GL_COLOR_BUFFER_BIT);glColor3f(0.0,0.0,1.0);glBegin(GL_POINTS);GLint x1=0,y1=0,x2=400,y2=200;GLint x=x1,y=y1;GLint dx=x2-x1,dy=y2-y1,dT=2*(dy-dx),dS=2*dy;GLint d=2*dy-dx;glV ertex2i(x,y);while(x<x2){x++;if(d<0)d=d+dS;else{y++;d=d+dT;}glV ertex2i(x,y);}glEnd();glFlush();}void k2() //k>1{glClear(GL_COLOR_BUFFER_BIT);glColor3f(0.0,1.0,0.0);glBegin(GL_POINTS);GLint x1=0,y1=0,x2=200,y2=400;GLint x=x1,y=y1;GLint dx=x2-x1,dy=y2-y1,dT=2*(dx-dy),dS=2*dx;GLint d=2*dx-dy;glV ertex2i(x,y);while(y<y2){y++;if(d<0)d=d+dS;else{x++;d=d+dT;}glV ertex2i(x,y);}glEnd();glFlush();}void k3() //-1<k<0{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glBegin(GL_POINTS);GLint x1=0,y1=400,x2=400,y2=200;GLint x=x1,y=y1;GLint dx=x2-x1,dy=y2-y1,dT=2*dy,dS=2*dy+2*dx;GLint d=2*dy-dx;glV ertex2i(x,y);while(x<x2){x++;if(d<0){y--;d=d+dS;}elsed=d+dT;glV ertex2i(x,y);}glEnd();glFlush();}void k4() //k<-1{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,1.0);glBegin(GL_POINTS);GLint x1=0,y1=400,x2=200,y2=0;GLint x=x1,y=y1;GLint dx=x2-x1,dy=y2-y1,dT=-2*dy-2*dx,dS=-2*dx;GLint d=-dy-2*dx;glV ertex2i(x,y);while(y>y2){y--;if(d>0)d=d+dS;else{x++;d=d+dT;}glV ertex2i(x,y);}glEnd();glFlush();}void main(int argc,char ** argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(200,100);glutCreateWindow("0<k<1(k=1/2)");glClearColor(1.0,1.0,0.0,0.0);gluOrtho2D(0.0,400.0,0.0,400.0);glutDisplayFunc(k1);glutCreateWindow("1<k(k=2)");glClearColor(1.0,0.0,1.0,0.0);gluOrtho2D(0.0,400.0,0.0,400.0);glutDisplayFunc(k2);glutCreateWindow("-1<k<0(k= -1/2)");glClearColor(0.0,1.0,1.0,0.0);gluOrtho2D(0.0,400.0,0.0,400.0);glutDisplayFunc(k3);glutCreateWindow("K<-1(k=-2)");glClearColor(0.0,1.0,0.0,0.0);gluOrtho2D(0.0,400.0,0.0,400.0);glutDisplayFunc(k4);glutMainLoop();}。
VC++6.0中利用图像扫描控件控制扫描仪

VC++6.0中利用图像扫描控件控制扫描仪
游明星
【期刊名称】《电脑编程技巧与维护》
【年(卷),期】2000(000)010
【摘要】本文主要介绍了一种简单地利用图像扫描控件控制扫描仪的方法。
利用该方法,可以方便地在自己的处理图像的应用程序中,或其它需要涉及扫描图像的应用程序中添加扫描功能。
【总页数】2页(P75-76)
【作者】游明星
【作者单位】无
【正文语种】中文
【中图分类】TP317.4
【相关文献】
1.利用扫描仪记录实物表面图像 [J], 冷雪峰;庞业光;董旭海
2.KODAK图像控件在扫描图像文档管理中的应用 [J], 康德纯;郭新阳;王殿龙
3.在Delphi中利用“Kodak图像扫描控件“控制扫描仪 [J], 刘识
4.利用扫描仪获取种子图像的研究 [J], 闸建文;孙玉峰;陈永艳
5.酶联斑点图像扫描仪控制系统 [J], 张从鹏; 解毅; 熊国顺; 张堉晨
因版权原因,仅展示原文概要,查看原文内容请购买。
直线扫描转换

1 实验目的1)掌握直线段的中点Bresenham扫描转换算法;2)掌握直线绘制类的设计实现;3)掌握菱形图案的生成方法。
2 实验要求1)直线绘制通过设计类似MFC的直线绘制类来实现,有类似的MoveTo()函数设置直线段起点,LineTo()函数设置直线段终点并完成绘制,还要有直线段颜色设置函数;2)直线的绘制采用中点Bresenham扫描转换算法实现,根据直线斜率k的范围区分五种不同的情况处理;3)调用设计实现的直线绘制类,在视图区绘制菱形线框,并要求各边颜色不同。
3 详细设计3.1 核心算法及类型设计使用中点Bresenham扫描算法完成绘制:CP2::CP2(){x=0.0;y=0.0;}CP2::~CP2(){}CP2::CP2(double x,double y){this->x=x;this->y=y;}CLine::CLine() //构造函数{}CLine::~CLine() //析构函数{}void CLine::SetLineColor(COLORREF color){clr=color;}void CLine::MoveTo(CP2p0){P0=p0;}void CLine::MoveTo(double x,double y){P0.x=x;P0.y=y;}void CLine::LineTo(double x,double y,CDC*pDC){CP2 p;p.x=x;p.y=y;LineTo(p,pDC);}void CLine::LineTo(CP2p1,CDC*pDC){P1=p1;CP2 p, t;if(fabs(P0.x-P1.x)<1e-6)//绘制垂线{if(P0.y>P1.y){t=P0; P0=P1; P1=t;}for(p=P0;p.y<P1.y;p.y++){pDC->SetPixelV (Round(p.x),Round(p.y),clr);}}else{double k,d;k=(P1.y-P0.y)/(P1.x-P0.x);if(k>1.0){if(P0.y>P1.y){t=P0; P0=P1; P1=t;}d=1-0.5*k;for(p=P0;p.y<P1.y;p.y++){pDC->SetPixelV(Round(p.x),Round(p.y),clr);if(d>=0){p.x++;d+=1-k;}elsed+=1;}}if(0.0<=k && k<=1.0)//绘制0<=k<=1{if(P0.x>P1.x){t=P0; P0=P1; P1=t;}d=0.5-k;for(p=P0; p.x<P1.x;p.x++){pDC->SetPixelV(Round(p.x),Round(p.y),clr);if(d<0){p.y++;d+=1-k;}elsed-=k;}}if(k>=-1.0&&k<0.0)//绘制-1<=k<0{if(P0.x>P1.x){t=P0; P0=P1;P1=t;}d=-0.5-k;for(p=P0; p.x<P1.x;p.x++){pDC->SetPixelV(Round(p.x),Round(p.y),clr);if(d>0){p.y--;d-=1+k;}elsed-=k;}}if(k<-1.0)//绘制k<-1{if(P0.y<P1.y){t=P0;P0=P1;P1=t;}d=-1-0.5*k;for(p=P0;p.y>P1.y;p.y--){pDC->SetPixelV(Round(p.x),Round(p.y),clr);if(d<0){p.x++;d-=1+k;}elsed-=1;}}}P0=p1;}调用直线类绘制菱形线框图:void CLineView::OnDraw(CDC* pDC){CLineDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;//设置坐标系CRect rect;GetClientRect(&rect);pDC->SetMapMode(MM_ANISOTROPIC);pDC->SetWindowExt(rect.Width(),rect.Height());pDC->SetViewportExt(rect.Width(),-rect.Height());pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);CLine*line= new CLine;//绘制坐标轴line->SetLineColor(RGB(0,0,0));//黑色line->MoveTo(CP2(-rect.Width()/2,0));//x轴line->LineTo(CP2(rect.Width()/2,0),pDC);line->MoveTo(CP2(0,-rect.Height()/2));//y轴line->LineTo(CP2(0,rect.Height()/2),pDC);//绘制直线int a=200;CP2 A (0,a);CP2 B (a,0);CP2 C (0,-a);CP2 D (-a,0);//绘制AB边line->SetLineColor(RGB(255,0,0));//红色line->MoveTo(A);line->LineTo(B,pDC);//绘制BC边line->SetLineColor(RGB(0,255,0));//绿色line->LineTo(C,pDC);//绘制CD边line->SetLineColor(RGB(0,0,255));//蓝色line->LineTo(D,pDC);//绘制DA边line->SetLineColor(RGB(255,255,0));//黄色line->LineTo(A,pDC);delete line;}3.2 程序设计实现及流程图使用Bresenham扫描转换算法进行直线绘制,需要根据斜率k值分别选择不同的误差项和初始值,除垂线外,可分为k<-1、-1<k<0、0<k<1和k>1四种情况。
五步直线扫描转换生成算法

五步直线扫描转换生成算法
欧阳开翠;白宝钢;曾令华
【期刊名称】《微计算机信息》
【年(卷),期】2006(022)018
【摘要】直线生成算法,尤其是直线扫描转换算法,是计算机图形学和计算机辅助设计等领域最基本、最重要的算法之一.本文提出了一种改进的直线生成算法--直线扫描转换的五步生成算法.该算法过给定的直线的始点和终点,可以一次计算得到并且点亮五个象素点,从而较传统的直线扫描转换算法成倍地提高了直线的生成速度,与著名的"四步法"相比,几乎没有增加复杂性,而速度则提高约20%,同时仍然保持传统直线扫描转换算法的精度.
【总页数】3页(P295-297)
【作者】欧阳开翠;白宝钢;曾令华
【作者单位】325027,浙江,温州,温州大学计算机科学与工程学院;325027,浙江,温州,温州大学计算机科学与工程学院;325027,浙江,温州,温州大学计算机科学与工程学院
【正文语种】中文
【中图分类】TP391.41
【相关文献】
1.直线扫描转换"距离比"算法 [J], 曾鸿
2.直线扫描转换中的最小生成机制 [J], 王晓云;王青
3.基于区域取样的直线扫描转换算法 [J], 何兴恒;林蝉
4.基于点到直线距离的直线扫描转换算法 [J], 陈幼明
5.五步直线扫描转换生成算法 [J], 欧阳开翠;白宝钢;曾令华
因版权原因,仅展示原文概要,查看原文内容请购买。
2.1直线扫描转换DDA算法

k
1
x i 1 x i 1 y i1 y i k
4 3 2 1
P0
P2
k 1 k 1
P1
0
1
2
3
4
5
x
k 1
用DDA方法画连接两点P0(0,0)和P1(2,5)的直线段
K=5/2=2.5>1 x 0 1 2 y 0 2.5 5 yi+1 = yi+k int(y+0.5) 0 3 5
y i kx i b y i 1 kx i 1 b
kx i k b kx i b k yi k
y 4 P1(5,3) 3 2 (xi,yi) 1 (xi+1,yi+1) P0(0,0) x 0 1 2 3 4 5
k ( x i 1) b
计算机图形学
第二章:光栅图形学算法
随着光栅显示器的出现,为了在计算机上处理、显 示图形,需要发展一套与之相适应的算法: 光栅图形学算法 光栅图形算法多数属于计算机图形的底层算法,很多 图形学的基本概念和思想都在这一章
光栅图形学算法的研究内容
直线段的扫描转换算法 多边形的扫描转换与区域填充算法 裁剪算法 反走样算法 消隐算法
5 4 3 2 1 0 1 2 3 4 5
再比如直线点从(0,0)到(2,100),也只用3个 点来表示
(1) k
1
x i 1 x i ? y i1 y i ?
(2)DDA画直线算法是否最优呢?若非,如何改进?
一、直线段的扫描转换算法 在数学上,直线上的有无穷多个。但当在计算机 光栅显示器屏幕上表示这条直线时需要做一些处理。
P1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
师学院数学与计算机科学学院
《计算机图形学》实验报告
实验序号:2 实验项目名称:直线的扫描转换学号2014210677 姓名王艳艳专业、班级 14计本一班
实验地点文科楼206 指导教师罗晓丽时间 2017.3.17 一、实验目的:
学会使用MFC,能够运用直线的三种扫描算法即数值微分算法(DDA算法)、中点画线算法和Bresenham画线算法绘制直线,并熟悉掌握制作过程。
二、实验环境:
Windows 7
VC++ 6.0
三、实验容:
打开vc6.0,点击新建—>工程—>MFC AppWizard [exe],创建项目名称(随便写),确定位置,然后点击确定。
选择创建的应用类型—>单文档—>完成。
点击确定。
DDA算法:
添加成员函数:
1.展开Wangyanyan classes—>右击WangyanyanView—>选择Add Member Funtion (添加成员函数)—>函数类型定义为void,函数描述为:DDAline—>点击确定
2.展开Wangyanyan classes—>CWangyanyanView—>在DDAline()函数里添加
形参int x0,int y0,int x1,int y1,int color,CClientDC & dc
3.双击CWangyanyanView,在public中添加代码:
void CWangyanyanjView::DDAline(int x0,int y0,int x1,int y1,int color,CClientDC & dc);
记住最后加分号
4.展开CWangyanyan—>双击OnDraw—>添加代码:
CClientDC dc(this);
DDAline(8,12,20,20,RGB(255,145,200),dc);
5.双击DDAline,在函数体编写如下代码:
void CDWangyanyanView::DDAline(int x0,int y0,int x1,int y1,int color,CClientDC & dc)
{
CPen newpen(PS_SOLID,1,color);
dc.SelectObject(&newpen);
int x,dx,dy,y,k;
dx=x1-x0;
dy=y1-y0;
k=dy/dx;
y=y0;
for(x=x0;x<=x1;x++)
{
dc.SetPixel(x,int(y+0.5),color);
y=y+k;
}
}
调试程序:
运行结果:
中点画线算法:添加成员函数
1.展开Wangyanyan classes—>右击CWangyanyanView—>选择Add Member Funtion(添加成员函数)—>函数类型定义为void,函数描述为:MidpointLine —>点击确定
2.展开classes—>CWangyanyanview,在MidpointLine函数里添加形参int
x0,int y0,int x1,int y1,int color,CClientDC & dc
3.双击CWangyanyanView,在public中添加代码:
void CWangyanyanView::MidpointLine(int x0,int y0,int x1,int y1,int color,CClientDC & dc);最后加分号
4.展开CWangyanyanView—>双击OnDraw—>添加代码:
MidpointLine(20,15,200,485,RGB(80,120,255), dc);
5.双击MidpointLine,在函数体编写如下代码:
调试程序:
运行结果:
Bresenham算法:
添加成员函数
1.展开Wangyanyan classes—>右击CWangyanyanView—>选择Add Member Funtion,函数类型定义为void,函数描述为:Bresenham_Line—>点击确定
2.点击classes—>CWangyanyanview,在Bresenham_Line函数里添加形参int x0,int y0,int x1,int y1,int color,CClientDC & dc
3.双击CWangyanyanView,在public中添加代码:
void CWangyanyanView::Bresenham_Line(int x0,int y0,int x1,int y1,int color,CClientDC & dc),最后加分号
4.展开CPwjView—>双击OnDraw—>添加代码:
Bresenham_Line(65,12,400,450,RGB(20,180,250), dc);
5.双击Bresenham_Line,在函数体编写如下代码:
int x,y,dx,dy,e,i;
dx=x1-x0;
dy=y1-y0;
e=-dx;
x=x0;
y=y0;
for(i=0;i<=dx;i++)
{
dc.SetPixel(x,y,color); x=x+1;
e=e+2*dy;
if(e>=0)
{
y=y+1;
e=e-2*dx;
}
}
调试程序:
运行结果:
. . . .
. . ..
教师评语
签名:
日期: 年 月 日
成绩。