OpenGL-实验2直线生成算法实现教学文案

合集下载

第4讲 直线生成

第4讲 直线生成

Bresenham算法
对于直线斜率k在0~1之间的情况,从给定线段的左端点 P0(x0, y0)开始,逐步处理每个后续列(x位置),并在扫描线 y值最接近线段的像素上绘出一点
yi+1 y
d2 d1
yi
xi
xi+1
Bresenham算法
对于直线斜率k在0~1之间的情况,从给定线段的左端点 P0(x0, y0)开始,逐步处理每个后续列(x位置),并在扫描线 y值最接近线段的像素上绘出一点
x
void DDALine(int x0,int y0,int x1,int y1,int color) 综合的c程序 int i; float dx, dy, length,x,y; if (fabs(x1-x0)>=fabs(y1-y0)) length=fabs(x1-x0); else length=fabs(y1-y0); dx = (x1-x0)/length; dy=(y1-y0)/length; i=1;x= x0;y= y0; while(i<=length) { SetPixel (int(x+0.5), int(y+0.5), color); x=x+dx; y=y+dy; i++;
光栅化和扫描转换是光栅图形学的基本问题,其算法的好 坏对系统的效率有直接的关系。
直线段的扫描转换
• 假定
(1)编程语言提供了一个显示像素函数: SetPixel(x,y,color); 其中,x和y为像素的位置坐标,color为像素的颜色。 (2)所给出的坐标数据为整数类型
直线段的扫描转换
• 问题
DDA算法
DDA算法与基本算法相比,减少了浮点乘法,提 高了效率。 但是x与dx、y与dy用浮点数表示,每一步要进行 四舍五入后取整,不利于硬件实现,因而效率仍 有待提高。

计算机图形学--直线段生成绘制的实现算法

计算机图形学--直线段生成绘制的实现算法

实验二直线段生成绘制的实现算法班级 08信计(2)班学号 20080502085 姓名王景超分数一、实验目的和要求:1.理解基本图形元素光栅化的基本原理2. 掌握一种基本图形元素光栅化算法3. 利用OpenGL实现直线光栅化的DDA算法二、实验内容:1. 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;2. 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;3. 根据示范代码,将其改造为圆的光栅化算法,写入实验报告;4. 了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

三、实验结果分析:1.该程序实现了三种算法的直线段绘制2.比较三种算法的结果:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法程序代码如下:/* WIN-TC BGI 图形编程模板*/#include "Conio.h"#include "graphics.h"#define closegr closegraphvoid initgr(void) /* BGI初始化*/{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/registerbgidriver(EGA VGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd, &gm, "");}/*-----------------------------数值微分法生成直线-----------------------------*/ void LineDDA1(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率m<-1*/{int y;float dy,dx,x,m;dx=x1-x0;dy=y1-y0;m=dx/dy;x=x0;for(y=y0;y>=y1;y--){putpixel((int)(x+0.5),y,color);x-=m;}}void LineDDA2(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率-1<=m<=1*/{int x;float dy,dx,y,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;}}void LineDDA3(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率m>1*/{int y;float dy,dx,x,m;dx=x1-x0;dy=y1-y0;m=dx/dy;x=x0;for(y=y0;y<=y1;y++){putpixel((int)(x+0.5),y,color);x+=m;}}/*----------------------------中点算法生成直线--------------------------------*/ void MidPointLine1(int x0,int y0,int x1,int y1,int color){ /*假定x0<x1,直线斜率m<-1*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=-2*dx-dy;incrE=-2*dx;incrNE=-2*(dx+dy);x=x0;y=y0;putpixel(x,y,color);while(y>=y1){if(d>0)d+=incrE;else{ d+=incrNE;x++;}y--;putpixel(x,y,color);}}void MidPointLine2(int x0,int y0,int x1,int y1,int color) { /*假定x0<x1,直线斜率-1<m<0*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=-(dx+2*dy);incrE=-2*dy;incrNE=-2*(dx+dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d<=0)d+=incrE;else{ d+=incrNE;y--;}x++;putpixel(x,y,color);}}void MidPointLine3(int x0,int y0,int x1,int y1,int color) { /* 假定x0<x1,直线斜率0<=m<=1 */int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=dx-2*dy;incrE=-2*dy;incrNE=2*(dx-dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d>0) d+=incrE;else{d+=incrNE;y++;}x++;putpixel(x,y,color);}}void MidPointLine4(int x0,int y0,int x1,int y1,int color){ /*假定x0<x1,直线斜率m>1*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=2*dx-dy;incrE=2*dx;incrNE=2*(dx-dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d<=0)d+=incrE;else{ d+=incrNE;x++;}y++;putpixel(x,y,color);}}/*-------------------------Bresenham算法生成直线-----------------------------*/ BresenhamLine(int x0,int y0,int x1,int y1,int color){int x,y,dx,dy,i;float m,d;dx=x1-x0;dy=y1-y0;m=dy/dx;d=0;x=x0;y=y0;putpixel(x,y,color);for(i=0;i<=dx;i++){d+=m;if(d>=0.5){y+=1;d-=1;}x++;putpixel(x,y,color);}}/*-------------------------------建立坐标系----------------------------------*/ void LineH(int x0,int x1,int y0,int color){int x,y;x=x0; y=y0;while(x<x1){putpixel(x,y,color);x++;}}void LineV(int y0,int y1,int x0,int color){int x,y;x=x0; y=y0;while(y<y1){putpixel(x,y,color);y++;}}int x0,y0,x1,y1,color,dx1,dy1;float m;int main(void){initgr(); /* BGI初始化*//*****此部分添加你自己的代码,例如line(25, 25, 220, 220);circle(100, 100, 50);等等*****//*-------------------------显示各种斜率的直线--------------------------------*/ MidPointLine1(300,400,340,240,125);MidPointLine2(240,340,400,300,255);MidPointLine3(240,300,400,340,255);MidPointLine4(300,240,340,400,255);LineH(240,400,320,255);LineV(240,400,320,255);outtextxy(398,318,">");outtextxy(280,420,"MidPointLine");LineDDA1(180,280,220,120,125);LineDDA2(120,220,280,180,255);LineDDA2(120,180,280,220,255);LineDDA3(180,120,220,280,255);LineH(120,280,200,255);LineV(120,280,200,255);outtextxy(180,300,"LineDDA");BresenhamLine(322,53,430,182,255);outtextxy(330,160,"Bresenham");/*----------------------------程序输入部分-----------------------------------*/ printf("firstpoint x0,y0:\n");scanf("%d,%d",&x0,&y0);printf("lastpoint x1,y1:\n");scanf("%d,%d",&x1,&y1);printf("color:\n");scanf("%d",&color);dx1=x1-x0;dy1=y1-y0;m=dy1/dx1;if(m<-1)MidPointLine1(x0,y0,x1,y1,color);else if(m>=-1&&m<0)MidPointLine2(x0,y0,x1,y1,color) ;else if(m>=0&&m<=1)MidPointLine3(x0,y0,x1,y1,color) ;elseMidPointLine4(x0,y0,x1,y1,color) ;getch(); /* 暂停一下,看看前面绘图代码的运行结果*/ closegr(); /* 恢复TEXT屏幕模式*/return 0;}运行结果:。

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

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

实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5);}// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y 方向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。

openGL画直线、圆、椭圆

openGL画直线、圆、椭圆
putpixel(xc,yc,-x,-y);
putpixel(xc,yc,-x,y);
putpixel(xc,yc,x,-y);
while(b*b*(x+1)<a*a*(y-0.5))
{
if(d1<0)
{
d1+=b*b*(2*x+3);
x++;
}
else
{
d1+=b*b*(2*x+3)+a*a*(-2*y+2);
{
glBegin(GL_POINTS);
glVertex3f(xc+x,yc+y,0);
glEnd();
}
void drawEllipse(int xc,int yc,int a,int b)
{
int x,y;
float d1,d2;
x=0;
y=b;
d1=b*b+a*a*(-b+0.25);
putpixel(xc,yc,x,y);
{
glBegin(GL_POINTS);
glVertex3f(xc+x,yc+y,0);
glVertex3f(xc-x,yc+y,0);
glVertex3f(xc+x,yc-y,0);
glVertex3f(xc-x,yc-y,0);
glVertex3f(xc+y,yc+x,0);
glVertex3f(xc-y,yc+x,0);
/* so this could be omitted: */
drawEllipse(250,250,60,40);
/* and flush that buffer to the screen */

OpenGL中点Bresenham绘制直线算法

OpenGL中点Bresenham绘制直线算法

OpenGL中点Bresenham绘制直线算法本⽂实例为⼤家分享了OpenGL中点Bresenham绘制直线算法,供⼤家参考,具体内容如下环境macos xcode编译器代码#include <GLUT/GLUT.h>#include <iostream>#include<iostream>#include<cstdlib>#include<ctime>using namespace std;float wid = 400; //设置窗⼝的⼤⼩,约定窗⼝必须为正⽅形float height = wid; //设置窗⼝的⼤⼩int numbers = 20; //设置划分的⽹格的个数float t = wid/numbers; //模拟像素下的单位1/*参数设置说明:输⼊直线的两点A(x1,y1);B(x2,y2)您应当确保参数范围在-400~400.且为整数。

*⽀持不同斜率*⽀持两点位置颠倒*/int x1 = -300,y1=-400,x2 =400,y2 = 100;void draw_point(float x, float y,int k_kind,int d_kind);float translater(int x);void swap(int &a, int &b){ int tmp = 0;tmp = b;b = a;a = tmp; }void bresenham(int x1, int y1,int x2, int y2){/*函数说明:bresenham算法部分参数说明:与openGL已有的划线函数⼀样,要求⽤户提供的是点的起点(x1,y1)和终点(x2,y2)为了便于观察,我们会绘制原像素下的直线。

这⾥的坐标要求是-1 ~ 1*/int k_kind = 0; //k_kind⽤来表⽰斜率的类型。

0是0~1;1是1~⽆穷;2是0~-1;3是负⽆穷~-1int d_kind =0; //d_kind⽤来表⽰dy正负的类型。

计算机图形学基础实验指导书

计算机图形学基础实验指导书

计算机图形学基础实验指导书目录实验一直线的生成 ............................................................... -..2.-实验二圆弧及椭圆弧的生成........................................................ -..3 -实验三多边形的区域填充 ......................................................... - (4)-实验四二维几何变换 ............................................................. -..5.-实验五裁剪算法 ................................................................. -..6.-实验六三维图形变换 ............................................................. -..7.-实验七BEZIER 曲线生成......................................................... -..8.-实验八交互式绘图技术实现........................................................ -..10-实验一直线的生成一、实验目的掌握几种直线生成算法的比较,特别是Bresenham 直线生成算法二、实验环境实验设备:计算机实验使用的语言: C 或Visual C++ 、OpenGL三、实验内容用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。

四、实验步骤直线Bresenham 生成算法思想如下1)画点(x i, y i), dx=x2-x i, dy=y2-y i,计算误差初值P i=2dy-dx , i=1;2)求直线下一点位置x i+i=x i+i 如果P i>0,贝U y i+i=y i+i,否则y i+i=y i;3)画点(x i+i ,y i+i );4)求下一个误差P i+i 点,如果P i>0,贝U P i+i=P i+2dy-2dx,否则P i+i=P i+2dy;i=i+i ,如果i<dx+i 则转步骤2,否则结束操作。

直线生成算法的实现

直线生成算法的实现

实验二:直线生成算法班级 13软件+道铁1班学号 20132110050115姓名丁益1.实验目的a)通过实验,进一步理解直线段扫描转换的DDA算法、中点画线自算法及bresenham算法的基本原理,掌握以上算法生成直线段的基本过程。

b)通过编程,掌握在C/C++环境下完成用DDA算法、中点画线算法及bresenham算法对任意直线段的扫描转换,以及在C/C++环境下完成用中点画圆及椭圆的绘制方法。

2.实验内容c)阅读《openGL三维程序设计》(电子书)第二部分第四章,掌握OpenGL基本建模方法,并调试其中程序。

d)参考教材第6章,编程实现整数DDA算法、中点画线法和Bresenham画线法,绘制直线(直线宽度和线型可自定)。

2.1 DDA直线生成2.1.1算法原理已知过端点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,y i+1=y i+k,即当x每递增1,y递增k。

由计算过程可知,y与k可能为浮点数,需要取y整数,源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。

2.1.2 算法流程2.1.3 算法实现关键代码#include<GL/glut.h>#include<math.h>void Init(){glClearColor(1.0,1.0,1.0,0.0);glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,200.0,0.0,150.0);}void lineDDA(int x0,int y0,int xEnd,int yEnd){int dx=xEnd-x0,dy=yEnd-y0,steps,k;float xIncrement, yIncrement, x=x0, y=y0;if(fabs(dx)>fabs(dy))steps=fabs(dx);elsesteps=fabs(dy);xIncrement=float(dx)/float(steps);yIncrement=float(dy)/float(steps);for(k=0;k<steps;k++){x+=xIncrement;y+=yIncrement;glBegin(GL_POINTS);glVertex2i(x,(int)(y+0.5));glEnd();}glFlush();}void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);lineDDA(50,50,100,120);}int main(int argc,char** argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow("Hello World");Init();glutDisplayFunc(myDisplay);glutMainLoop();return 0;}2.1.4算法运行示例及中间结果2.2 Brese nham直线生成2.2.1算法原理Bresenham算法的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。

lesson03-直线生成算法市公开课特等奖市赛课微课一等奖课件

lesson03-直线生成算法市公开课特等奖市赛课微课一等奖课件
△y=yb-ya。 则S,t可用下式计算: S=△y/△x·(r+1)-q t=(q+1)-△y/△x·(r+1) S-t=2·△y/△x·(r+1)-2q-1
Ti q+1
t
q
s
Si
△x(S-t)=2(r·△y-q·△x)+2△y-△x 其中: △x>0。 r r+1
令di=△x(S-t),则di与S-t符号相同 只要判别di符号就可确定下一点坐标是Si还是Ti。。
LESSON 03
基本图形生成算法
第1页
基本图形生成算法
• 总体目标: 掌握二维图形学基本思想,了解 二维图形生成基本原理
• 掌握直线段生成算法、反走样算法。 • 掌握圆弧生成及线形处理 • 掌握字符生成基本思想
第2页
基本概念
• 光栅显示器上显示图形, 称之为光栅图形。 • 确定最正确迫近图形象素集合, 并用指定颜色
程序。
第15页
2.1.2中点画线算法
void Midpoint Line (int x0,int y0,int x1, int y1,int color)
{ int a, b, d1, d2, d, x, y;
a=y0-y1; b=x1-x0;d=2*a+b;
d1=2*a;d2=2* (a+b);
q+1 q
Ti
t s
Si
这两个假设点之间误差S,t大小。
若S>t(或S-t>0),则取点Ti,反之取点Si。。 r r+1
第18页
2.1.3 Bresenham直线生成算法原理
假设直线是从(xa,ya)至(xb,yb), 假如把直线平移使点(xa,ya) 与原点重合,则直线方程可写成

计算机图形学实验报告

计算机图形学实验报告

计算机图形学基础实验报告院系:计算机科学学院班级:2012级4班姓名:彭晓学号:21209010434实验二直线生成算法的实现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将会画出一条直线。

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

贵州大学计算机图形学实验报告----直线生成算法

贵州大学计算机图形学实验报告----直线生成算法

贵州大学计算机图形学实验报告学院:计算机科学与信息学院专业:软件工程班级: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。

计算机图形学--实验二---基本图形

计算机图形学--实验二---基本图形

实验二基本图形(元)生成技术(一)直线生成算法一、实验目的在一个图形系统中,基本图形(也称为图元、图素等)的生成技术是最基本的,任何复杂的图形都是由基本图形组成的,基本图形生成的质量直接影响该图形系统绘图的质量。

所以,需要设计出精确的基本图形生成算法,以确保图形系统绘图的精确性。

本次实验的目的就是验证直线生成的三种扫描算法,并要求对基本算法进行扩充和改进,包括:利用Visual C++实现三种直线生成算法,验证算法的正确性;二、实验任务1.理解三种直线生成算法思想,写出实现程序;2.添加鼠标功能,实现交互式画直线程序;3.将10个像素作为步距单位,编出Bresenham算法的示例。

三、基本知识和实验步骤任务一:实现DDA画线程序实验步骤:1.建立一个DDALine的工程文件;2.添加ddaline()成员函数方法:在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“add member function…”,定义如下的成员函数:void ddaline(CDC* pDC,int x0,int y0,int x1,int y1,COLORREF color);3.编写自定义的成员函数ddaline()程序void CDDALineView::ddaline(CDC* pDC, int x0, int y0, int x1, int y1, COLORREF color) {int length,i;float x,y,dx,dy;length=abs(x1-x0);if (abs(y1-y0)>length)length=abs(y1-y0);dx=(x1-x0)/length;dy=(y1-y0)/length;x=x0+0.5;y=y0+0.5;for (i=1;i<=length;i++){pDC->SetPixel((int)x,(int)y,color);x=x+dx;y=y+dy;}}4.编写OnDraw()函数void CDDALineView::OnDraw(CDC* pDC){CDDALineDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereddaline(pDC,100,100,400,100,RGB(255,0,0));ddaline(pDC,400,100,400,400,RGB(0,255,0));ddaline(pDC,400,400,100,400,RGB(0,0,255));ddaline(pDC,100,400,100,100,RGB(255,255,0));ddaline(pDC,100,100,400,400,RGB(255,0,255));ddaline(pDC,100,400,400,100,RGB(0,255,255));}}5.编译、调试和运行程序,查看程序结果。

计算机图形学-直线的生成算法的实现

计算机图形学-直线的生成算法的实现

实验二 直线的生成算法的实现班级 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 生成算法等。

实验报告2(直线的生成算法绘制)

实验报告2(直线的生成算法绘制)

实验二:直线的生成算法绘制实验目的:实现C语言编写图形程序。

学会了解VC++的基本应用同时了解TC图形环境配置,学习简单的图形画法,并比较画法的优劣,尝试在计算机实现,得到图形,验证比较图形。

实验内容:直线的生成算法:DDA和Bresenham算法// DDA算法生成直线void CMyView:: OnDdaline(){CDC* pDC=GetDC();//获得设备指针int xa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);//定义直线的两端点,直线颜色int x,y;float dx, dy, k;dx=(float)(xb-xa), dy=(float)(yb-ya);k=dy/dx, y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pDC->SetPixel (x,int(y+0.5),c);y=y+k;}}if(abs(k)>=1){for (y=ya;y<=yb;y++){pDC->SetPixel (int(x+0.5),y,c);x=x+1/k;}}ReleaseDC(pDC);}说明:(1)以上代码理论上通过定义直线的两端点,可得到任意端点之间的一直线,但由于一般屏幕坐标采用右手系坐标,屏幕上只有正的x, y值,屏幕坐标与窗口坐标之间转换知识请参考第3章。

(2)注意上述程序考虑到当k 1的情形x每增加1,y最多增加1;当k>1时,y每增加1,x相应增加1/k。

在这个算法中,y与k用浮点数表示,而且每一步都要对y进行四舍五入后取整。

//Bresenham算法生成直线void CMyView::OnBresenhamline(){CDC* pDC=GetDC();int x1=100, y1=200, x2=350, y2=100,c=RGB(0,0,255);int i,s1,s2,interchange;float x,y,deltax,deltay,f,temp;x=x1;y=y1;deltax=abs(x2-x1);deltay=abs(y2-y1);if(x2-x1>=0) s1=1; else s1=-1;if(y2-y1>=0) s2=1; else s2=-1;if(deltay>deltax){temp=deltax;deltax=deltay;deltay=temp;interchange=1;}else interchange=0;f=2*deltay-deltax;pDC->SetPixel(x,y,c);for(i=1;i<=deltax;i++){if(f>=0){if(interchange==1) x+=s1;else y+=s2;pDC->SetPixel(x,y,c);f=f-2*deltax;}else{if(interchange==1) y+=s2;else x+=s1;f=f+2*deltay;}}}说明:(1)以上程序已经考虑到所有象限直线的生成。

OpenGL-实验2直线生成算法实现教学文案

OpenGL-实验2直线生成算法实现教学文案

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

2. 实验内容(1) 根据所给的直线光栅化的示范源程序, 在计算机上编译运行, 输出正确结果。

(2) 指出示范程序采用的算法, 以此为基础将其改造为中点线算法或Bresenham 算法,写入实验报告。

(3) 根据示范代码,将其改造为圆的光栅化算法,写入实验报告。

(4) 了解和使用OpenGL 的生成直线的命令,来验证程序运行结果。

3. 实验原理示范代码原理DDA 算法。

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

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

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

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

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

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

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

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

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

另一方面,gIBegin 支持的方式除了GL_POINTS和GL_LINES还有GL LINE STRIP GL LINEL0O P、GL TRIANGLE S GL TRIANGLE STRIP GL TRIANGLE_FA等几何图元。

【OpenGL学习】四种绘制直线的算法

【OpenGL学习】四种绘制直线的算法

【OpenGL学习】四种绘制直线的算法我是⽤MFC框架进⾏测试的,由于本⼈也没有专门系统学习MFC框架,代码若有不⾜之处,请指出。

⼀,先来⼀个最简单的DDA算法DDA算法全称为数值微分法,基于微分⽅程来绘制直线。

①推导微分⽅程如下:②,dM时间步长的倒数的详解:可以看到当|k|<=1时dx=1或者-1,此时的x为计长⽅向当|k|>1时dy=1或者-1,此时的y为计长⽅向绘制时需要⽤dM来控制绘制的点数③绘制像素的问题:为了“⽅便”管理算法,我为不同的绘制函数新建了⼀个类了。

(其实可以写到⼀个类⾥⾯。

)④代码实现:MyDDA.cpp1 #include "stdafx.h"2 #include "MyDDA.h"345MyDDA::MyDDA()6{7}8910 MyDDA::~MyDDA()11{12}1314void MyDDA::SetDc(CDC * dc)15{16this->pdc = dc;17}1819void MyDDA::Moveline(CPoint start, CPoint end)20{21int x1, x2;22int y1, y2;23 x1 = start.x;24 x2 = end.x;25 y1 = start.y;26 y2 = end.y;27float dm = 0;28if (abs(x2 - x1) >= abs(y2 - y1))29 dm = abs(x2 - x1);30else31 dm = abs(y2 - y1);32float dx = (float)(x2 - x1) / dm;33float dy = (float)(y2 - y1) / dm;34float x = x1 + 0.5;35float y = y1 + 0.5;36int i = 0;37while (i<dm) {38this->pdc->SetPixel((int)x, (int)y, RGB(0, 0, 0));39 x += dx;40 y += dy;41 i += 1;42 }43总结:其实这个算法还算是挺简单的,就是要确定是X还算Y为计长⽅向,需要注意的是循环过程中计长⽅向⾃增1,另⼀个⽅向按照当直线在计长⽅向⾃增1时,直线在轴上的投影的⼤⼩⾃增就可以了。

直线生成实验报告

直线生成实验报告

直线生成实验报告直线生成实验报告引言:直线生成是计算机图形学中的一个重要概念,它在许多应用中都有广泛的应用,如计算机游戏、CAD软件等。

本实验旨在通过编写程序,实现直线生成算法,并对不同算法进行比较和分析。

一、实验目的本实验的主要目的是掌握直线生成算法的原理和实现方法,并通过实验验证算法的正确性和效率。

具体目标包括:1. 理解直线生成的基本原理和算法;2. 实现直线生成算法的程序;3. 比较和分析不同算法在不同情况下的性能差异。

二、实验过程1. 算法原理直线生成算法的核心是根据两点确定直线的斜率和截距,然后根据斜率的大小以及截距的正负确定直线上的像素点。

常见的直线生成算法有数字微分分析法(DDA算法)和中点画线法(Bresenham算法)。

2. 程序实现为了实现直线生成算法,我们选择使用Python编程语言。

首先,我们需要定义一个画布,并在画布上绘制直线。

然后,根据所选的算法,编写相应的函数来生成直线。

最后,我们可以通过调用这些函数,将直线绘制到画布上。

3. 算法比较与分析为了比较不同算法的性能,我们可以通过以下几个方面进行评估:- 精度:比较生成的直线与真实直线的误差;- 效率:比较算法的执行时间;- 适用性:比较算法在不同情况下的适用性,如直线斜率、直线长度等。

三、实验结果与讨论通过实验,我们得到了以下结果:1. DDA算法在直线斜率接近于0或无穷大的情况下表现较好,但在其他情况下可能存在精度问题;2. Bresenham算法在直线斜率为正且小于1的情况下表现较好,但在其他情况下可能存在精度问题;3. 在效率方面,Bresenham算法通常比DDA算法更快;4. 对于较长的直线,Bresenham算法能够更好地处理。

综上所述,不同的直线生成算法在不同情况下表现出不同的性能。

在实际应用中,我们需要根据具体情况选择合适的算法。

此外,我们还可以通过优化算法来提高直线生成的效率和精度。

结论:本实验通过实现直线生成算法并比较不同算法的性能,加深了对直线生成原理的理解。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

2.实验内容(1)根据所给的直线光栅化的示范源程序, 在计算机上编译运行, 输出正确结果。

(2)指出示范程序采用的算法, 以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告。

(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告。

(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。

3.实验原理示范代码原理DDA算法。

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

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

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

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

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

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

例如:glBegin(GL P0INTS) ,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 L0〇P、GL TRIANGLES、GL TRIANGLE STRIP、GL TRIANGLE_FAN等几何图元。

(2) 首次打开窗口、移动窗口和改变窗口大小时, 窗口系统都将发送一个事件, 以通知程序员。

如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc注册的函数。

该函数必须完成下列工作:①重新建立用作新渲染画布的矩形区域。

②定义绘制物体时使用的坐标系。

如:void Reshape(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION) ;glLoadIdentity() ;gluOrtho2D(0.0, (GLdouble) w,0.0,(Gldouble)h);}在GLUT内部, 将给该函数传递两个参数: 窗口被移动或修改大小后的宽度和高度, 单位为像素。

glViewport()调整像素矩形,用于绘制整个窗口。

接下来三个函数调整绘图坐标系,使左下角坐标为(0,0),右上角坐标为(w,h)。

4.实验代码#include<GL/glut.h>void SetPixel(int x,int y){//画点glBegin(GL_POINTS);glVertex2i(x,y);//设置点坐标glEnd();}void swap(int *a,int *b)//交换函数{int temp=*a;*a=*b;*b=temp;}int abs(int a,int b){if(a>b)return (a-b);else return (b-a);}void Bres_Line(int x0,int y0,int x1,int y1)// Bresenham算法{glColor3f(1.0f,0.0f,0.0f);SetPixel(x0,y0);int dx=abs(x1,x0);//200int dy=abs(y1,y0);//300if(dx==0&&dy==0)return ;int flag=0;if(dx<dy){flag=1;swap(&x0,&y0);swap(&x1,&y1);swap(&dx,&dy);}int tx=(x1-x0)>0?1:-1;int ty=(y1-y0)>0?1:-1;int curx=x0;int cury=y0;int dS=2*dy;int dT=2*(dy-dx);int d=dS-dx;while(curx!=x1){if(d<0)d+=dS;else{cury+=ty;d+=dT;}glPointSize(2);if(flag){SetPixel(cury,curx);}else{SetPixel(curx,cury);}curx+=tx;}}void LineDDA(int x0,int y0,int x1,int y1/*,int color*/){ float x,y;float m,dy,dx;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;glColor3f(1.0f,1.0f,1.0f);glPointSize(2);for(x=x0;x<=x1;x++){SetPixel(x,(y+0.5));y+=m;}}void Cirpot(int x0,int y0,int x,int y){SetPixel((x0+x),(y0+y));SetPixel((x0+y),(y0+x));SetPixel((x0+y),(y0-x));SetPixel((x0+x),(y0-y));SetPixel((x0-x),(y0-y));SetPixel((x0-y),(y0-x));SetPixel((x0-y),(y0+x));SetPixel((x0-x),(y0+y));}void BresCricle(int x0,int y0,double r){glColor3f(0.0f,0.0f,1.0f);int x,y,d;x=0;y=(int) r;d=int(3-2*r);while(x<y){Cirpot(x0,y0,x,y);if(d<0)d+=4*x+6;else{d+=4*(x-y)+10;y--;}x++;}if(x==y)Cirpot(x0,y0,x,y);}void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,1.0f);glRectf(25.0,25.0,75.0,75.0);glPointSize(1);glBegin(GL_POINTS);glColor3f(0.0f,1.0f,0.0f);glVertex2f(100.0f,200.0f);glEnd();LineDDA(0,0,200,300);//点线BresCricle(100,200,100);Bres_Line(0,0,300,100);glBegin(GL_LINES);glColor3f(1.0f,0.0f,0.0f);glVertex2f(100.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex2f(180.0f,240.0f);glEnd();glFlush();}void Init(){glClearColor(0.0,0.0,0.0,0.0);glShadeModel(GL_SMOOTH);}void Reshape(int w,int h){glViewport(0,0,(GLsizei) w,(GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);//坐标系定义}int main(int argc,char *argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow("Hello World!");Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMainLoop();return 0;}5.6.实验结果7.实验分析在书本中代码呈现出的直线是一条斜率为1的线,而按照数据,线条斜率为1.5,分析其原因是在LineDDA函数中,m,x,y等值的类型都为int型,造成了数据的丢失,所以斜率发生了变化。

相关文档
最新文档