计算机图形学直线生成算法
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
简述画直线的几种操作方式

简述画直线的几种操作方式一、概述画直线是计算机图形学中的基本操作之一,通常用于绘制线条、边框等。
在计算机图形学中,有多种方式可以实现画直线的功能。
本文将介绍几种常见的画直线操作方式。
二、DDA算法DDA算法是一种基本的画直线算法,它采用逐点比较的方式来确定像素点的位置。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,不断计算下一个像素点的位置,并在屏幕上绘制。
优点:实现简单,适用于硬件实现。
缺点:精度不高,容易出现锯齿状。
三、Bresenham算法Bresenham算法是另一种常见的画直线算法,它采用整数运算来确定像素点位置。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,根据当前位置和误差值选择下一个像素点,并在屏幕上绘制。
优点:精度高,画出的直线平滑。
缺点:实现复杂,不适用于硬件实现。
四、中点画线算法中点画线算法是一种基于Bresenham算法的改进版,它通过引入中点来减少计算量。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,根据当前位置和误差值选择下一个像素点,并在屏幕上绘制;4. 在误差值发生变化时,更新中点的位置。
优点:精度高,计算量较小。
缺点:实现复杂,不适用于硬件实现。
五、直线段裁剪直线段裁剪是指将一条直线段截取为位于窗口内部的一段直线。
常见的裁剪算法有Cohen-Sutherland算法和Liang-Barsky算法。
Cohen-Sutherland算法将窗口分为九个区域,并通过比较端点与窗口边界的关系来确定哪些部分需要保留。
Liang-Barsky算法则通过计算交点来确定截取后的直线段。
六、总结以上介绍了几种常见的画直线操作方式,包括DDA算法、Bresenham算法、中点画线算法以及直线段裁剪算法。
计算机图形学 直线段生成绘制的实现算法

实验二直线段生成绘制的实现算法班级 08信计学号60姓名杨平萍分数一、实验目的和要求:1、掌握光栅图形显示基本原理2、熟悉直线的DDA算法、Bresenham算法绘制直线3、上机操作实现DDA算法、Bresenham算法。
二、实验内容:1、了解DDA算法、Bresenham算法的原理2、编程实现DDA算法、Bresenham算法绘制直线段3、分析对比二算法三、程序执行和运行结果DDA算法的实现#include"stdio.h"#include"graphics.h"void DDALine(int x1,int y1, int x2,int y2){double dx, dy,e,x,y;int i;dx=x2-x1;dy=y2-y1;e=(fabs(dx)>fabs(dy))? fabs(dx):fabs(dy);dx/=e;dy/=e;x=x1;y=y1;for(i=1;i<=e;i++){putpixel((int)(x+0.5),(int)(y+0.5),YELLOW);x+=dx;y+=dy;}}void main(){int driver=VGA;int mode=VGAHI;initgraph(&driver,&mode,"");DDALine(100,150,250,300 );getch();closegraph();}运行结果:Bresenham算法的实现:#include<stdio.h>#include<graphics.h>void Bresenhamline(int x1,int y1,int x2,int y2){int x,y,dx,dy,p;x=x1;y=y1;dx=x2-x1;dy=y2-y1;p=2*dy-dx;for(;x<=x2;x++){putpixel(x,y,RED);if(p>=0){y++;p+=2*(dy-dx);}else{p+=2*dy;}}}main(){int driver=VGA;int mode=VGAHI;initgraph(&driver,&mode,"");Bresenhamline(50,150,200,250);getch();closegraph();}运行结果:3、对比Bresenham算法、DDA算法、中点算法三种算法的像素逼近效果和程序执行速度三两种算法的像素逼近效果和程序执行速度。
计算机图形学常用算法及代码大全

2。
1。
1 生成直线的DDA算法数值微分法即DDA法(Digital Differential Analyzer),是一种基于直线的微分方程来生成直线的方法.一、直线DDA算法描述:设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得= m =直线的斜率(2-1)可通过计算由x方向的增量△x引起y的改变来生成直线:x i+1=x i+△x (2-2)y i+1=y i+△y=y i+△x·m (2-3) 也可通过计算由y方向的增量△y引起x的改变来生成直线:y i+1=y i+△y (2-4)x i+1=x i+△x=x i+△y/m (2-5) 式(2-2)至(2-5)是递推的.二、直线DDA算法思想:选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向上的增量为一个象素单位(△x=1),然后利用式(2-1)计算另一个方向的增量(△y=△x·m=m)。
通过递推公式(2-2)至(2-5),把每次计算出的(x i+1,y i+1)经取整后送到显示器输出,则得到扫描转换后的直线。
之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的象素应均匀,这在下图中可看出。
另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还是负值。
三、直线DDA算法实现:1、已知直线的两端点坐标:(x1,y1),(x2,y2)2、已知画线的颜色:color3、计算两个方向的变化量:dx=x2-x1dy=y2-y14、求出两个方向最大变化量的绝对值:steps=max(|dx|,|dy|)5、计算两个方向的增量(考虑了生成方向):xin=dx/stepsyin=dy/steps6、设置初始象素坐标:x=x1,y=y17、用循环实现直线的绘制:for(i=1;i〈=steps;i++){putpixel(x,y,color);/*在(x,y)处,以color色画点*/x=x+xin;y=y+yin;}五、直线DDA算法特点:该算法简单,实现容易,但由于在循环中涉及实型数的运算,因此生成直线的速度较慢。
分别解释直线生成算法dda法、中点画线法和bresenham法的基本原理

分别解释直线生成算法dda法、中点画线法和bresenham法的基本原理DDA直线生成算法、中点画线法和Bresenham法都是计算机图形学中用于生成直线的算法。
以下是这三种算法的基本原理:1.DDA直线生成算法(Digital Differential Analyzer):DDA算法是一种基于差分运算的直线生成算法。
其基本原理是,通过计算直线起点和终点之间的差值(横向差值dx 和纵向差值dy),并根据步长来决定下一个像素点的位置。
算法首先确定差值中绝对值较大的一方作为基准,步长设为1,另一方则按比例进行调整,以保持线段的斜率不变。
在实现过程中,DDA算法需要遍历每一个像素点,根据差值的正负和大小来确定新像素点的位置。
2.中点画线法:中点画线法的基本原理是,通过计算线段上当前像素点与相邻两个像素点构成的线段与理想直线的距离,来决定下一个像素点的位置。
具体实现时,设定线段的中点为M,理想直线与线段的交点为Q。
通过比较M和Q的位置关系来确定下一个像素点:若M在Q上方,则取上方的像素点为下一个点;若M在Q下方,则取下方的像素点为下一个点;若M与Q重合,则可任意选择上方或下方的像素点。
中点画线法以中点M作为判别标志,逐点生成直线。
3.Bresenham法:Bresenham算法的原理是基于直线的斜率和截距来计算每个像素点的位置。
在计算机屏幕上,每个像素点都有一个坐标值。
Bresenham算法通过计算直线上每个像素点的坐标值来绘制直线,避免了使用浮点数运算,从而提高了计算效率。
在实现过程中,Bresenham算法根据直线的斜率以及当前像素点的位置,计算出下一个像素点的位置,并逐点绘制出直线。
《计算机图形学》实验报告

《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。
通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。
二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。
开发环境为 PyCharm。
三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。
它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。
Bresenham 算法则是一种基于误差的直线生成算法。
它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。
在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。
2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。
通过不断迭代计算中点的位置,逐步生成整个圆。
在实现过程中,需要注意边界条件的处理和误差的计算。
3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。
旋转变换是围绕一个中心点将图形旋转一定的角度。
缩放变换则是改变图形的大小。
通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。
4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。
扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。
在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。
四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。
根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。
生成直线的dda算法

生成直线的dda算法
DDA算法是一种简单而有效的直线生成算法,可以使用数值计算来生成线段坐标。
本文将介绍DDA算法的实现原理、优缺点以及在实际应用中的使用情况。
一、DDA算法的实现原理:
DDA算法使用数值计算来计算每个像素的坐标,然后在屏幕上直接画出直线。
具体实现步骤如下:
1. 取两个端点(x1,y1)和(x2,y2)。
2. 计算dx,dy,m(斜率)和steps(使用的步骤)。
3. 计算xinc和yinc以确定绘制的方向。
4. 分配像素的坐标并在屏幕上绘制直线。
二、DDA算法的优缺点:
1. 优点:
(1)DDA算法能够生成直线。
(2)算法简单,易于实现。
(3)计算速度快,对硬件要求低。
2. 缺点:
(1)DDA算法产生的直线锯齿状。
(2)当线的斜率趋近于无穷大时,计算会出现分母无限大的错误,需要特殊处理。
(3)当线的斜率趋近于0时,计算会出现分母为0的错误,需要特殊处理。
三、DDA算法的应用:
DDA算法被广泛应用于计算机图形学中,常被用来生成直线和绘制几何图形。
例如,绘制线条、矩形、椭圆等形状,都会使用DDA算法。
此外,还有一些基于DDA算法的算法,如圆算法、填充算法等。
四、总结:
DDA算法是一种简单而有效的直线生成算法,具有计算速度快、对硬件要求低等优点。
然而,由于其产生的直线锯齿状,导致其在某些应用场景下难以满足要求。
在实际应用中,DDA算法被广泛应用于生成直线和绘制几何图形的场景中。
贵州大学计算机图形学实验报告----直线生成算法

贵州大学计算机图形学实验报告学院:计算机科学与信息学院专业:软件工程班级:102班优点:用整数加法代替了DDA数值微分法中的浮点数加法及取整运算,大大提高了算法的效率。
缺点:在计算d的符号时,需要做4个加法和2个乘法改进:因为d是x和y的线性函数,因此可采用增量计算。
通过计算可得对于|k|<=1的情况d的初值为a+0.5b,当d>=0,M在L上方,增量d1为a;当d<0,M在L下方,增量d2为a+b。
对于|k|>1的情况d的初值为0.5a+b,当d>=0,M在L下方,增量d1为b;当d<0,M在L上方,增量d2为a+b。
三、Bresenham划线算法该算法是计算机图形学领域中使用最为广泛的直线扫描转换算法,该划线算法类似与中点划线算法,也是由误差项符号决定下一个像素右边点还是右上点。
基本原理:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的优点在于增量计算,使得对于每一列只要检查一个误差项的符号,就可以确定该列所求的像素。
根据直线的斜率来确定变量在x 或y方向递增一个单位。
另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。
这一距离称为误差。
由以上原理,为方便计算,令e = d-0.5,e的初值为-0.5,增量为k。
当 e>=0时,取当前像素(xi,yi)的右上方像素(xi+1,yi+1),e减小1,而当e<0时,更接近于右方像素(xi+1,yi)。
Bresenham算法的分析:优点:高效,巧妙地采用了e = d-0.5,e的初值为-0.5来简化运算,把e和0.5的比较转化成了e和0的比较,使得每次画点只需考虑误差项增量的符号即可。
斜率显示:中点划线算法斜率显示:Bresenham算法斜率显示:注:可根据教学需要对以上栏目进行增减。
表格内容可根据内容扩充。
计算机图形学 直线生成算法实现

实验二直线生成算法实现班级 08信计学号 80姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、掌握几种常见的直线的生成算法3、实现直线生成的算法二、实验内容:1.了解直线的生成原理2.掌握几种基本的直线生成算法:DDA算法、bresenham画线法、中点画线法3.实现直线生成的,在屏幕上任意生成一条直线三、实现程序程序1#define pi 3.141592#define MAX(a,b) (a>b)? a:b#define MIN(a,b) (a<b)? a:b#include "graphics.h"#include "math.h"struct rectangle{int xmin;int xmax;int ymin;int ymax;};struct point{float x;float y;};struct point pot[2];struct rectangle rect={150,490,100,380};int x=0,y=0;void zhongxing(int x,int y,int s){ int i;for(i=x-5;i<=x+5;i++){ putpixel(i,y,s);}for(i=y-5;i<=y+5;i++){ putpixel(x,i,s);}}void add(int x,int y,int i){pot[i].x=x;pot[i].y=y;}int clip(float q,float d,float *t0,float *t1){ float r;if(q<0){ r=d/q;if(r>*t1)return(0);else if(r>*t0){ *t0=r;return(1);}}else if(q>0){ r=d/q;if(r<*t0)return(0);else if(r<*t1){ *t1=r;return(1);}}else if(d<0)return(0);return(1);}void liang(struct point * pot,struct rectangle * rect){ float delatx,delaty,t0,t1;t0=0;t1=1;delatx=pot[1].x-pot[0].x;if(clip(-delatx,pot[0].x-rect->xmin,&t0,&t1))if(clip(delatx,rect->xmax-pot[0].x,&t0,&t1)){ delaty=pot[1].y-pot[0].y;if(clip(-delaty,pot[0].y-rect->ymin,&t0,&t1))if(clip(delaty,rect->ymax-pot[0].y,&t0,&t1)){ line((int)(pot[0].x+t0*delatx),(int)(pot[0].y+t0*delaty), (int)(pot[0].x+t1*delatx),(int)(pot[0].y+t1*delaty)); }}}void main(){int driver=DETECT,mode; int i=0,j,key; registerbgidriver(EGAVGA_driver);initgraph(&driver,&mode,"\\tc"); initgraph(&driver,&mode,"\\tc");zhongxing(x,y,4);setcolor(3);rectangle(150,100,490,380);/**/for(;;){ if(bioskey(1)){ key=bioskey(0);if(key==0x4d00){ zhongxing(x,y,0);x+=5;zhongxing(x,y,4);rectangle(150,100,490,380);}if(key==0x011b){printf("esc be press");break;}if(key==0x4b00){ zhongxing(x,y,0);x-=5;zhongxing(x,y,4);rectangle(150,100,490,380);}if(key==0x5000){zhongxing(x,y,0);y+=5;zhongxing(x,y,4);rectangle(150,100,490,380);}if(key==0x4800){zhongxing(x,y,0);y-=5;zhongxing(x,y,4);rectangle(150,100,490,380);}if(key==0x1c0d){ add(x,y,i);circle(x,y,3);i+=1;}if(key==0x3920){liang(pot,&rect);for(j=0;j<2;j++){ pot[j].x=0;pot[j].y=0;}i=0;}}}getch();closegraph();}程序2(1)DDA算法程序实现的完整源程序#include<stdio.h>#include<graphics.h>#include<math.h>#define YS 100000dda_line(int xa,int ya,int xb,int yb,int c){float delta_x,delta_y,x,y;int dx,dy,steps,k;dx=xb-xa;dy=yb-ya;if(abs(dx)>abs(dy)) /*判断步长的方向*/steps=abs(dx); /*steps作为控制数K<1*/elsesteps=abs(dy); /*steps作为控制数K>1*/delta_x=(float)dy / (float)steps; /*值为±1域±1/m*/ delta_y=(float)dy / (float)steps; /*值为±1域±m*/ x=xa;y=ya;putpixel(x,y,c); /*画起点,c为点的颜色*/for(k=1;k<=steps;k++) /*循坏画点成直线*/{x+=delta_x;y+=delta_y;putpixel(x,y,c);delay(YS);}}main(){int x1=250,y1=250,x2=300,y2=300,c=5;int dx,dy,n,k,i,f;int x,y;int gdriver,gmode;gdriver=DETECT;initgraph(&gdriver,&gmode," ");dda_line(x1,y1,x2,y2,c);getch();closegraph();}(2)改进的Bresenham画线算法程序实现的完整源程序#include<stdio.h>#include<graphics.h>#include<math.h>#define YS 100000bresenham_line(int x0,int y0,int x1,int y1,int c){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++){putpixel(x,y,c++);/*c++不同描点不同颜色*/delay(YS);x++,e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}main(){int x0=100,y0=100,x1=200,y1=200,c=1;int gdriver,gmode;gdriver=DETECT;initgraph(&gdriver,&gmode," ");bresenham_line(x0,y0,x1,y1,c);getch();closegraph();}(3)中点算法实现的完整源程序#include <stdio.h>#include <stdlib.h>#include <math.h>#include <conio.h>#include <graphics.h>#define rad 0.0174532925#define NUMBER 24/*此程序写出的图形,(0,0)在左上方,即以原y轴的负半轴为正,x轴不变,类似于抛物运动。
直线生成算法的实现

直线生成算法的实现1.数字微分法:数字微分法是直线生成算法的一种基本方法,其核心思想是通过对直线的斜率进行离散化处理,从而得到直线上的像素点。
具体步骤如下:步骤1:根据直线的起点和终点坐标,计算直线的斜率k=(y2-y1)/(x2-x1)。
步骤2:根据斜率k的值,判断直线属于四种情况:0<=k<=1、k>1、-1<=k<0、k<-1步骤3:对于不同的斜率范围,采取不同的策略进行像素点的生成。
对于斜率0<=k<=1,直线的横坐标增加1,纵坐标按照斜率增加1,每次增加1后判断纵坐标是否需要增加1对于斜率k>1,直线的纵坐标增加1,横坐标按照1/k增加。
每次增加1后判断横坐标是否需要增加1对于斜率-1<=k<0,直线的横坐标减少1,纵坐标按照斜率减少1,每次减少1后判断纵坐标是否需要减少1对于斜率k<-1,直线的纵坐标减少1,横坐标按照1/,k,减少。
每次减少1后判断横坐标是否需要减少1步骤4:重复步骤3直到直线上所有的像素点都生成完毕。
2. Bresenham算法:Bresenham算法是一种角度固定的画线算法,通过判断像素点与理想直线之间的距离来确定下一个像素点的位置。
具体步骤如下:步骤1:根据直线的起点和终点坐标,计算直线的斜率k=(y2-y1)/(x2-x1)。
步骤2:初始化误差项d=-1/2步骤3:循环直到达到直线的终点。
步骤4:根据斜率k的值,判断直线属于四种情况。
对于0<=k<=1,判断d<k-1/2,如果满足则x坐标加1,否则x、y坐标同时加1对于k>1,判断d<-1/2,如果满足则y坐标加1,否则x、y坐标同时加1对于-1<=k<0,判断d>k+1/2,如果满足则x坐标减1,否则x、y坐标同时加1对于k<-1,判断d>-1/2,如果满足则y坐标减1,否则x、y坐标同时加1步骤5:更新误差项d=d+k。
计算机图形学基本图形生成算法

y= k· x+b
k=0.571429
b=0.428571
2 X[0]=1 y0 X[1]=2
Y[0]=1 Y[0]=1 Y[1]=kx[1]+b=1.57 Y[1]=y0+k=1.57 Y[2]=y1+k=2.14 Y[2]=kx[2]+b=2.14 Y[3]=y2+k=2.71 Y[3]=kx[3]+b=2.71 Y[4]=y3+k=3.28 Y[4]=kx[4]+b=3.28 Y[5]=y4+k=3.85 Y[5]=kx[5]+b=3.85 Y[6]=y5+k=4.4 Y[6]=kx[6]+b=4.4 Y[7]=5 Y[7]=5
第3章 基本图形生 成算法
1 直线生成算法(DDA、BRES) 2 圆生成算法(Mid) 3 多边形填充算法(扫描线、区域) 4 字符图元算法
2015/4/19
1
图元
• 图元:图形软件包中用了描述各种几何 图形元素的函数称为图形输出原语,简 称图元。 • 描述对象几何要素的输出图元一般称为 几何图元。点的定位和直线段是最简单 的几何图元。 • 在选定坐标系中指定一个图形的几何要 素后,输出图元投影到该输出设备显示 区域对于的二维平面上,并扫描转换到 帧缓存的整数像素位置。
2015/4/19
5
1 直线生成算法(DDA、BRES) 2 圆生成算法(Mid) 3 多边形填充算法(扫描线、区域) 4 字符图元算法
1 直线的DDA算法
2015/4/19
6
OpenGL画点和画线函数 1) 画点函数 glVertex*( ); (*={234}{sifd}[v]) 表示该函数有后缀,指 明空间尺寸、坐标数据类型或向量形式描述。 Ex: glBegin(GL_POINTS); glVertex2i(100,50); glEnd(); glBegin(GL_POINTS); glVertex2i(100,50); glVertex2i(75,90); glVertex2i(300,590); glEnd();
计算机图形学 实验一直线生成算法报告

实验一直线生成算法一、实验目的及要求:1.学习C语言的基本绘图方法;2. 实习直线基本生成算法;3.了解光栅图形显示器的工作原理和特点;4.掌握课本所介绍的图形算法的原理和实现。
5. 基于光栅图形显示器,在c环境中使用基本图形生成算法画根粗细不同的直线。
1.)写出完整的DDA画线算法程序,使其可以画任意直线;2.)写出完整的中点画线算法程序,使其可以画任意直线;3.)写出完整的Breaenham画线程序,使其可以画任意直线;二、理论基础:1、DDA算法:实现的关键是如何步进和步进的方向:步进的正或负,决定能否正确的到达终点。
步进的大小:它控制了变化最大的步进,令其为单位步进,而另一个方向的步进必小于1 ,这样不论斜率|m|≤1否,都会使直线的亮度均匀。
依公式:则下一点坐标为:2、中点画法:假设x坐标为xp的各像素点中,与直线最近者已确定,为(xp,yp)。
那么,下一个与直线最近的像素只能是正右方的P1(xp+1,yp)或右上方的P2(xp+1,yp+1)两者之一。
再以M表示P1与P2的中点,即M=(xp+1,yp+0.5)。
又设Q是理想直线与垂直线x=xp+1的交点。
若M在Q的下方,则P2离直线近,应取为下一个像素;否则应取P1。
3、Bresenham算法:假设我们需要由 (x0, y0) 这一点,绘画一直线至右下角的另一点(x1, y1),x,y分别代表其水平及垂直座标。
在此我们使用电脑系统常用的座标系,即x座标值沿x轴向右增长,y座标值沿y轴向下增长。
因此x及y之值分别向右及向下增加,而两点之水平距离为x1 − x0且垂直距离为y1-y0。
由此得之,该线的斜率必定介乎于1至0之间。
而此算法之目的,就是找出在x0与x1之间,第x行相对应的第y列,从而得出一像素点,使得该像素点的位置最接近原本的线。
三、算法设计与分析:1、DDA算法:(1)已知过端点P0 (x0, y0), P1(x1, y1)的直线段L :y=kx+b(2)直线斜率为 :k=(y1-y0)/(x1-x0)(3)Xi+1=Xi+ε*ΔXYi+1=Yi+ε*ΔY 其中,ε=1/max(|ΔX|,|ΔY|)max(|ΔX|,|ΔY|)= |ΔX| (|k|<=1)|ΔY| (|k|>1)(4)|k|<=1时:Xi+1=Xi+(或-)1Yi+1=Yi+(或-)k|k|>1时:Xi+1=Xi+(或-)1/kYi+1=Yi+(或-)1这种方法直观,但效率太低,因为每一步需要一次浮点乘法和一次舍入运算。
dda直线生成算法原理

dda直线生成算法原理DDA(Digital Differential Analyzer)直线生成算法是一种用于计算机图形学中的直线生成算法,用来在屏幕上绘制直线。
它是一种基本的直线生成算法,其原理简单易懂且计算速度较快,因此在计算机图形学中得到了广泛的应用。
DDA直线生成算法的基本思想是通过增量的方式来计算直线上的像素点坐标。
具体而言,该算法先确定直线上的两个端点坐标,然后根据两点坐标的差值计算直线的斜率。
根据斜率的大小可以确定每一步直线将朝x轴或y轴方向前进一个单位。
在DDA直线生成算法中,我们首先确定直线起点和终点的坐标(x0, y0)和(x1, y1),然后分别计算直线在x轴和y轴方向上的增量(dx和dy)。
dx是终点x坐标与起点x坐标的差值,dy是终点y坐标与起点y 坐标的差值。
通过计算斜率的绝对值(|m|),我们可以确定每一步的方向和步长。
当斜率小于等于1时,我们选择在x轴方向每次移动1个单位,并通过斜率m的倒数来确定y坐标上的增量。
当斜率大于1时,我们选择在y轴上每次移动1个单位,并通过斜率m来确定x坐标上的增量。
算法中定义了一个以起点为基准的循环,直到达到目标点的坐标时终止。
在每一次循环迭代中,我们根据斜率的大小选择在x轴或y轴方向上移动1个单位,并同时调整x坐标和y坐标的增量。
具体实现过程如下:1.计算dx和dy: dx = x1 - x0,dy = y1 - y0。
2.计算步长: abs(dx)和abs(dy)中较大的那个作为步长,即steps = max(abs(dx), abs(dy))。
3.计算增量: x_increment = dx / steps,y_increment = dy / steps。
4.初始化当前坐标: x = x0,y = y0。
5.绘制线段:在每次循环中,将当前坐标(x, y)作为像素点,然后更新当前坐标为(x + x_increment, y + y_increment)。
计算机图形学直线生成

int i=1;
while(i<=length){ SetPixel (x, y, color); x=x+dx; y=int (y+dy ); i++;
13
六、直线DDA算法特点:
DDA算法简单,实现容易;
DDA算法与基本算法相比,减少了浮点乘法,提高了效率。
但是由于在循环中涉及实型数的运算(x与dx、y与dy用浮点 数表示),每一步要进行取整,因此生成直线的速度较慢, 不利于硬件实现,因而效率仍有待提高。
yi+1 y yi
P2
d2
Pd
xi
Xi+1
1
P1
y值要么不变,要么递增 1,可通过比较d1和d2来 决定。
图3-3 根据误差量来确定理想的像素点
18
二、直线Bresenham算法描述:
Bresenham算法也是采用递推步进的办法,令每次最大变 化方向的坐标步进一个象素,同时另一个方向的坐标依据误差 判别式的符号来决定是否也要步进一个象素。
第2章 基本光栅图形生成技术
显示器是由离散像素组成的矩阵,在绘制具有连续性质的 直线、曲线或区域等基本图形时,需要确定最佳逼近它们的像 素,这个过程称为光栅化。
虽然几乎所有的程序设计语言都提供了线、圆弧、填充等 的绘制函数,但只有学习了基本图形的生成原理和算法,才能 超越具体程序设计语言的限制,满足用户的特殊绘图要求。 假定,编程语言提供了一个显示像素函数: SetPixel(x,y,color); 其中,x和y为像素的位置坐标,color为像素的颜色。
( i+1,int( i+1+0.5))
x
y
( i, i)
计算机图形学-直线的生成算法的实现

实验二 直线的生成算法的实现班级 08信计2班 学号 59 姓名 分数一、实验目的和要求1.理解直线生成的基本原理。
2.掌握几种常用的直线生成算法。
3.利用Visual C++实现直线生成的DDA 算法。
二、实验内容1.了解直线的生成原理,尤其是Bresenham 画线法原理。
2.掌握几种基本的直线生成算法:DDA 画线法、Bresenham 画线法、中点画线法。
3.利用Visual C++实现直线生成的DDA 算法,在屏幕上任意生成一条直线。
三、实验步骤1.直线的生成原理:(1)DDA 画线法也称数值微分法,是一种增量算法。
是一种基于直线的微分方程来生成直线的方法。
(2)中点画线法原理以下均假定所画直线的斜率[0,1]k ∈,如果在x 方向上的增量为1,则y 方向上的增量只能在01之间。
中点画线法的基本原理是:假设在x 坐标为p x 的各像素点中,与直线最近者已经确定为(,)p p P x y ,用小实心圆表示。
那么,下一个与直线最近的像素只能是正右方的1(1,)p p P x y +,或右上方的2(1,1)p p P x y ++,用小空心圆表示。
以M 为1P 和2P 的中点,则M 的坐标为(1,0.5)p p x y ++。
又假设Q 是理想直线与垂直线1p x x =+的交点。
显然,若M 在Q 的下方,则2P 离直线近,应取2P 为下一像素点;若M 在Q 的上方,则1P 离直线近,应取1P 为下一像素点。
(3)B resenham 画线法原理直线的中点Bresenham 算法的原理:每次在主位移方向上走一步,另一个方向上走不走步取决于中点偏差判别式的值。
给定理想直线的起点坐标为P0(x0,y0),终点坐标为P1(x1,y1),则直线的隐函数方程为:0b kx y y)F(x,=--= (3-1)构造中点偏差判别式d 。
b x k y y x F y x F d i i i i M M -+-+=++==)1(5.0)5.0,1(),(⎩⎨⎧≥<+=+)0( )0( 11d y d y y i i i(1) 当d<0时b x k y y x F d i i i i i -+-+=++=+)2(5.1)5.1,2(1k d k b x k y i i i -+=-+-+-+=11)1(5.0⑵ 当d ≥0时b x k y y x F d i i i i i -+-+=++=+)2(5.0)5.0,2(1k d k b x k y i i i -=--+-+=)1(5.02.实现前面所述的各种直线生成算法,包括DDA 算法、中点生成算法、Bresenham 生成算法等。
计算机图形学 3.1直线生成算法

yi 0.5 k ( xi 1) b 1 k d i 1 k
⑵当d≥0时
(3-4)
d i 1 F ( xi 2, yi 0.5) yi 0.5 k ( xi 2) b yi 0.5 k ( xi 1) b k d i k
P2 Q
∴欲判断M点是在Q点上方还是
在Q点下方,只需把M代入F(x,y), 并检查它的符号。
P=(xp,yp) P1
3.1.2 中点画线法
构造判别式: d=F(M)=F(xp+1,yp+0.5) =yp+0.5-k(xp+1)-b 当d<0,M在直线(Q点)下方,取右 上方P2;
P2 Q
当d>0,M在直线(Q点)上方,取正
(3-5)
2.中点偏差判别式的初始值
直线的起点坐标为P0(x0,y0),x为主位 移方向。因此,第一个中点是(x 0+1,y 0+0.5),相应的d的初始值为:
d 0 F ( x0 1, y0 0.5) y0 0.5 k ( x0 1) b
y 0 kx0 b k 0.5
已知起点、终点,欲生成一条直线,算法应满足
几点要求:
(1)所画的线要直; (2)具有精确的起点和终点; (4)画直线速度快。
(3)所显示的亮度沿直线不变,与直线的长度和方向无关;
3.1.1 数值微分法(DDA算法)
假定直线的起点、终点分别为:(x0,y0), (x1,y1),且都为整数。
。
。 。
(X i , Yi)
M(x i+2,y i+1.5) M(x i+1,y i+0.5) P(xi,yi) M(x i+1,y i+0.5) P(xi,yi)
计算机图形学-直线生成算法实验报告

湖南工商大学课程实验报告(注:本实验报告文件请以自己的学号姓名为文件名,保存关闭后提交)课程名计算机图形学班级计科16xx 学号1609xxxxx 姓名宋x实验名称直线生成算法一、实验目的1.理解三种直线生成算法思想;2.写出实现程序;二、实验步骤1.建立一个DDALine的工程文件;2.添加ddaline()成员函数;3.编写自定义的成员函数ddaline()程序;4.编写OnDraw()函数;5.编译、调试和运行程序,程序结果如下。
同时尝试画几条不同颜色的直线;6.参照以上方法自行完成中点画线法和Bresenham法生成直线的算法程序。
三、实验代码DDA算法程序(任意斜率):void CTestView::ddaline(CDC *pDC, int x0, int y0, int x1, int y1, COLORREF color){float x,y,dx,dy;int i,length;if(abs(x1-x0)>abs(y1-y0))length=abs(x1-x0);elselength=abs(y1-y0);dx=(float)(x1-x0)/length; //这里一定要转化为实型dy=(float) (y1-y0)/length;x=x0;y=y0;for(i=1;i<=length;i++){pDC->SetPixel(int(x+0.5),int(y+0.5),color);x=x+dx;y=y+dy;}}中点画线算法(斜率0<k<1):void CTestView::MidpointLine(CDC *pDC, int x0, int y0, int x1, int y1, int color) {int a,b,delta1,delta2,d,x,y;a=y0-y1;b=x1-x0;d=2*a+b;delta1=2*a;delta2=2*(a+b);x=x0;y=y0;pDC->SetPixel(x,y,color);while(x<x1){if(d<0){x++;y++;d+=delta2;}else{x++;d+=delta1;}pDC->SetPixel(x,y,color);}}OnDraw函数:void CTestView::OnDraw(CDC* pDC){CTestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereddaline(pDC,30,30,400,300,RGB(59,207,237));MidpointLine(pDC,100,100,500,200,RGB(0,0,255));}四、实验结果截图。
计算机图形学DDA

计算机图形学DDA计算机图形学DDA算法DDA算法是⼀个经典的画直线算法,也是直线⽣成算法中最简单的⼀种。
它的原理⽐较简单,是⼀种数值微分的⽅法,这也是本系统中第⼀个接触增量思想的算法。
它是利⽤直线最基本的格式,斜截式:y=kx+b来实现的。
我们都知道在计算机中乘法的运算效率远低于加法,⽽DDA算法就是将效率低下的乘法计算改成了效率相对⾼的加法运算。
⾸先需要计算出斜率k=(y1-y0)/(x1-x0)(x1!=x2) 每⼀次x移动⼀个像素,y值就像相应的增加k。
但像素值都是整数,⽽所求出的k不⼀定都是整数,所以要对求出的下⼀个像素坐标值进⾏取整处理。
最后将计算得到的像素点,赋上颜⾊,就基本可以达到拟合这⼀线段的⽬的。
在编写算法时,要注意直线斜率的问题。
x+1只适⽤于0<k<1的情况。
K>1时将算法中的x,y调换,变成y+1去计算。
K<-1时⽤y+1计算;-1<k<0时⽤x+1计算。
//DDA画直线函数private void dda(int x1, int y1, int x2, int y2, Color c){double x, y, xadd, yadd;x = x1;y = y1;int max_abs = Math.Max((Math.Abs(x1 - x2)),(Math.Abs(y1 - y2)));xadd = (double)(x2 - x1) / (double)max_abs;yadd = (double)(y2 - y1) / (double)max_abs;for (int i = 1; i < max_abs; i++){mydraw.SetPixel((int)x, (int)y,c); x += xadd;y += yadd;}}上⾯这段DDA算法是我在了解了基本思路之后,分情况讨论编写出来⼀个DDA之后,偶然间发现还可以继续合并,经过长时间的修改最终获得了这段看起来⽐较简单的代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10
举例:用DDA方法扫描转换连接两点P0(0,0)和P1 (5,2)的直线段
X int(y+0.5) y+0.5 0 0 0 1 0 0.4+0.5 2 1 0.8+0.5 3 1 1.2+0.5 4 2 1.6+0.5
2014-5-10
11
特点1 注意上述分析的算法仅适用于|k| ≤1的情形。在这种 情况下,x每增加1, y最多增加1。当 |k| > 1时,必须 把x,y地位互换,y每增加1,x相应增加1/k。 特点2 在这个算法中,y与k必须用浮点数表示,而且每一步 都要对y进行四舍五入后取整。这使得它不利于硬件实 现
运算,不利于硬件实现; DDA算法,效率低)
条件:
同DDA算法 斜 率:
m [0,1]
直线段的隐式方程((x0,y0)(x1,y1)两端点) F(x,y)=ax+by+c=0 式中 a=y0-y1,b=x1-x0,c=X0Y1-X1Y0
2014-5-10
17
画直线段的过程中,当前象素点为(xp, yp),一个象素点有 两种可选择点p1(xp+1, yp)或p2(xp+1, yp+1)。若M=(xp+1, yp+0.5)为p1与p2之中点,Q为理想直线与x=xp+1垂线的交 点。当M在Q的下方,则P2 应为下一个象素点;M在Q的上 方,应取P1 为下一点。就是中点画线法的基本原理。
2014-5-10 28
为方便计算,令e=d-0.5,e的初值为-0.5, 增量为k。当e≥0时,取当前象素(xi,yi) 的右上方象素(xi+1,yi+1);而当e<0 时,更接近于右方象素(xi+1,yi)。
2014-5-10
29
Bresenham画线算法程序 void Bresenhamline (int x0,int y0,int x1, int y1,int color) { int x, y, dx, dy; float k, e; dx = x1-x0; dy = y1- y0; k=dy/dx; e=-0.5; x=x0; y=y0; for (i=0; i<=dx; i++) { Putpixel (x, y, color); x=x+1; e=e+k; if (e>= 0) { y++, e=e-1;} } }
2014-5-10
4
2 直线段的扫描转换
目标:求与直线段充分接近的像素集 像素间均匀网格 整型坐标系 两点假设
直线段的宽度为1 直线段的斜率:
m [1,1]
2014-5-10 5
基本图形点阵转换算法评价
所显示图形的精度 算法的时间和空间复杂性
两者冲突,权衡折衷
2014-5-10
6
描绘线条图形的要求
直线段要显得笔直 线段端点位置要准确 线段的亮度要均匀 转换算法速度要快
2014-5-10
7
DDA( digital differential analyzer)算法
条件:
, y1) 待扫描转换的直线段:P 0 ( x0, y0) P 1 ( x1
斜率:m y / x
2014-5-10
P1
22
d的初始值 d0=F(X0+1,Y0+0.5)=F(X0,Y0)+a+0.5*b 因 (X0,Y0) 在 直 线 上 , F(X0 , Y0)=0, 所 以 , d0=a+0.5*b d的增量都是整数,只有初始值包含小数,可以 用2d代替d, 2a改写成a+a。 算法中只有整数变量,不含乘除法,可用硬件 实现。
x x1 x0, y y1 y0 交算法:
划分区间[x0,x1]: x0 , x1 ,, xn , 其中xi 1 xi 1 计算纵坐标: yi m xi B 取整: {( x , y )}n
i i i 0
2014-5-10
1
扫描转换直线段
• DDA算法 • 中点画线法 • Bresenham算法
圆弧、椭圆弧扫描转换
• 中点算法
• Bresenham算法 • 内接多边形迫近法* • 等面积多边形逼近法*
2014-5-10
2
1 简单的二维图形显示流程
2014-5-10
3
图形显示前需要:扫描转换+裁剪 ● 裁剪 ---〉扫描转换:最常用,节约计算时间。 ● 扫描转换 ---〉裁剪:算法简单; ● 扫描转换到画布 --〉位块拷贝:算法简单,但耗时耗 内存。常用于字符显示。
2014-5-10 20
问题:判断距直线最近的下一个象素点
构造判别式:d=F(M)=F(Xp+1,Yp+0.5) 由d>0,<0可判定下一个象素,
P2 P
P1
2014-5-10
21
要判定再下一个象素,分两种情形考虑:
1)若d≥0,取正右方象素P1,再下一个象素判定, 由: d1=F(Xp+2,Yp+0.5)=a(Xp+2)+b(Yp+0.5)+c=d+a , d的增量是a 2)若d<0,取右上方象素P2,再下一个象素, 由:d2=F(Xp+2,Yp+1.5)=d+a+b d的增量为a+b P2 P
2014-5-10
23
中点算法程序 MidPointLine(x0,y0,x1,y1,color) {int x0,y0,x1,y1,color; int a,b,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; SetPixel(x,y,color); while (x<x1) { if (d<0) { x++; y++; d +=d2;} else { x++; d +=d1;} SetPixel(x,y,color); } }
2014-5-10
18
直线的正负划分性
点与直线的关系:on: F(x,y)=0; up: F(x, y)>0; down: F(x, y)<0;
2014-5-10
19
欲判断中M在Q点的上方还是下方,只要把M代 F(x,y),并判断它的符号。 构造判别式: d=F(M)=F(xp+1, yp+0.5) =a(xp+1)+b(yp+0.5)+c 当d<0,M在Q点下方,取P2为下一个象素; 当d>0,M在Q点上方,取P1为下一个象素; 当d=0,选P1或P2均可,约定取P1为下一个象 素
2014-5-10 24
举例 用中点画线方法扫描转换连接两点P0(0,0)和P1 (5,2)的直线段
a=y0-y1=-2; b=x1-x0=5; d0=2*a+b=1; d1=2*a=-4; d2=2*(a+b)=6 x y d 0 0 1 1 0 -3 d1 2 1 3 d2 3 1 -1 d1 4 2 5 d2 5 2 1
第二讲 二维基本图形生成
所谓图元的生成,是指完成图元的参数表示形式(由图 形软件包的使用者指定)到点阵表示形式(光栅显示系 统刷新时所需的表示形式)的转换。通常也称扫描转换 图元
§1 §2 §3 §4 §5 简单的二维图形显示流程 直线段的扫描转换 圆弧的扫描转换 易画曲线的正负法 线画图元的属性控制
2014-5-10 25
画线Bresenham算法
Bresenham算法是计算机图形学领域使用最广泛的直 线扫描转换算法。该方法类似于中点法,由误差项符 号决定下一个象素取右边点还是右上点。 本算法由Bresenham在1965年提出该方法最初是为数 字绘图仪设计的,后来被广泛地应用于光栅图形显示 和数控(NC)加工 算法原理如下:过各行各列象素中心构造一组虚拟网 格线。按直线从起点到终点的顺序计算直线与各垂直 网格线的交点,然后确定该列象素中与此交点最近的 象素。该算法的巧妙之处在于采用增量计算,使得对 于每一列,只要检查一个误差项的符号,就可以确定 该列的所求象素。
2014-5-10 26
工作原理:根据直线的斜率在x或y的方向每次都 只递增一个象素单位,另一个方向的增量为0或1
2014-5-10
27
设直线方程为y=kx+b,其中k=dy/dx。 假 设x列的象素已经确定为xi,其行坐标为yi。 那么下一个象素的列坐标为xi+1,而行坐 标要么不变为yi,要么递增1为yi+1。 是否增1取决于如图所示误差项d的值。因为 直线的起始点在象素中心,所以误差项d的 初值d0=0。X下标每增加1,d的值相应递 增直线的斜率值k,即d=d+k。 当d≥0.5时,直线与xi+1列垂直网格交点最 接近于当前象素(xi,yi)的右上方象素(xi +1,yi+1);而当d<0.5时,更接近于右 方象素(xi+1,yi)。
{( xi , yi ,r )}in0
8
yi,r round( yi ) (int)(yi 0.5)
2014-5-10
复杂度:乘法+加法+取整
DDA算法(增量算法) yi 1 m xi 1 B m ( xi 1) B m xi B m yi m
2014-5-10 14
DDA直线生成算法的伪语言描述如下: begin if abs(x2﹣x1)≥abs(y2﹣y1) then lenght﹦abs(x2﹣x1) else lenght﹦abs(y2﹣y1) endif △x﹦(x2﹣x1)/lenght △y﹦(y2﹣y1)/lenght x﹦x1 y﹦y1 k﹦ 1 while(k≤lenght) putpixel(x,y) x﹦x﹢△x y﹦y﹢△y k﹦ k﹢ 1 endwhile end