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)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。

如果使用的是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 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;
glColor3f (1.0f, 1.0f, 0.0f);
glPointSize(1);
for(x=x0;x<=x1; x++)
{
glBegin (GL_POINTS);
glVertex2i (x, (int)(y+0.5));
glEnd ();
y+=m;
}
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 0.0f, 0.0f);
glRectf(25.0, 25.0, 75.0, 75.0);
glPointSize(5);
glBegin (GL_POINTS);
glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.0f, 0.0f); glEnd ();
LineDDA(0, 0, 200, 300);
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_FLAT);
}
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;
}
注:glShadeModel选择平坦或光滑渐变模式。

GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。

5.思考题
示范代码有个小错误,能否指出并改正?请将结果写入实验报告。

合集下载

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

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

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

CG第3章基本图形生成算法C课件

CG第3章基本图形生成算法C课件

int dy=yr-y1, dx=xr-x1;
int ie;
/* integer scaled error term */
x=xl; y=yl; /* start at left endpoint */
ie =dx-2 *dy; /* initialize the error term */
while (x <= xr){ /* pixel-drawing loop */
2024/2/22
16
0≤m≤1时Bresenham算法的步骤为:
1. 输入直线的两端点P0(x0,y0)和P1(x1,y1)。
2. 计算初始值△x, △y, d=Δx-2Δy , x=x0, y=y0;
3. 绘制点(x,y),根据d的符号进行如下操作: 若d<0,则(x,y)更新为(x+1,y+1),d更新为
yi1
yi yi
1
(di 0) (di 0)
Pa (xi 1, yi 1)
Q
问题:算法结束了吗? 有无优化的可能?
M (xi 1, yi 1/ 2)
P(xi , yi ) Pb (xi 1, yi )
注意:计算di 的运算量并不小.
2024/2/22
12
误差项的递推 若di<0,有
di1 F ( xi 2, yi 1.5) yi 1.5 m(xi 2) b yi 1.5 m(xi 1) b m di 1 m
M (xi 2, yi 1.5)
Q
M (xi 1, yi 0.5)
P(xi , yi )
2024/2/22
di<0
13
误差项的递推 若di≥0,有
di1 F (xi 2, yi 0.5) yi 0.5 m(xi 2) b yi 0.5 m(xi 1) b m di m

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

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

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

CG02图形基础算法

CG02图形基础算法

算法原理
选择表示直线的最佳像素的位置,即用 最靠近直线的网格点来代表这一直线。根据 直线的斜率确定或选择变量x或y每次递增一 个单位,另一个变量y或x每次增量为0或1, 这取决于理论直线段与最近像素点的距离。 避免了低效率的取整运算。
y 设直线段的斜率m∈[0,1](即倾角≦45°)其 中m=≨y/≨x,则要生成的直线的微分方程为: Yi+1,ri yi - 1
Pu(x i+1,y i)
(d1 0) (d1 0)
(3-17)
P(xi,yi)
M(x i+1,y i-0.5) Pd(x i+1,yi-1)
x
图3-13 上半部分像素点的选取
上半部分Ⅰ的递推公式
图3-13中,为了能够继续判断椭圆上的每个点,需要给 出中点偏差判别式d1的递推公式和初始值。
A(0,b)
y向分量 法矢量 C( a 2 /
a 2 b2 , b 2 / a 2 b 2
)
x向分量 B(a,0)
椭圆的中点Bresenham算法的原理:在部分Ⅰ:每次在 主位移x方向上走一步,y方向上退不退步取决于中点偏差判别 式的值;在部分Ⅱ:每次在主位移方向y上退一步,x方向上走 不走步取决于中点偏差判别式的值。
Pk(xk,yk) Pu(xk+1,yk)
M
Pb(xk+1,yk-1)
≥0
f(M)= <0
M点在圆外,取Pb
M点在圆内,取Pu
Bresenham生成圆弧算法
A 我们仍讨论第二个1/8圆。设有半径为R圆心在 坐标原点。 AB为第二个1/8圆的圆弧,圆的方程为: R
x2+y2=R2
Pi-1(xi-1,yi-1)是已选中的点,则下一个点应在 Hi(xi,yi-1)和Li(xi,yi-1-1)选取。 设有圆弧S满足: xHi2+yHi2-Rs2+ xLi2+yLi2-Rs2=0 2-18

直线生成算法的实现

直线生成算法的实现

实验二:直线生成算法班级 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算法的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。

精品课件-计算机图形学-第3章 基本图形元素生成算法


第 3 章 基本图形元素生成算法
图3.1 中点画线示意图
第 3 章 基本图形元素生成算法
设Q是理想直线与垂直线x=xP+1的交点。 若M 在Q的下方, 则P2离理想直线近, 应取为下一个像素; 否 则应取P1。 为此, 我们构造判别式
d=F(M)=F(xP+1,yP+0.5)=a(xP+1)+b(yP+0.5)+c 当d<0时, M在直线下方, 应取右上方的P2作为下 一个像素; 当d>0时, M在直线上方, 则应取正右方的P1; 当d=0时, 约定取正右方的P1。
根据以上分析, 可得中点画圆法算法如下: void MidPoint -Circle(r, color) int r, clor; { int x, y;
float d; x=0; y=r; d=1.25-r; putpixel(x, y, color); while(x<y)
{ if(d<0) { d+=2*x+3; x++; }
float k, e; dx=x1-x0; dy=y1-y0; k=dy/dx; e=-0.5; x=x0; y=y0;
第 3 章 基本图形元素生成算法
for(i=0; i<=dy; i++) { putpixel(x, y, color); x=x+1; e=e+k; if(e>=0){ y=y+1; e=e-1; } }
第 3 章 基本图形元素生成算法
x++; }
else { e+=(deltax+deltay); deltax+=2; deltay+=2; x++; y--; }

基本图形元素的生成算法


计 算 机 图 形 学
第三章 基本图形元素的生成算法
计 算 机 图 形 学
光栅显示器上显示的图形,称之为光栅图形。光 栅显示器可以看作是一个象素矩阵,在光栅显 示器上显示的任何一个图形,实际上都是一些 像素的集合。由于对一个具体的光栅显示器来 说,象素个数是有限的,象素的颜色和灰度等 级也是有限的,象素是有大小的,所以光栅图 形只是近似的实际图形。如何使光栅图形最完 美地逼近实际图形,便是光栅图形学要研究的 内容。确定最佳逼近图形的像素集合的过程称 为图形的扫描转换或光栅化。
计 算 机 图 形 学
第三章 基本图形元素的生成算法
a)
b)
图3.2 直线的生成
c)
计 算 机 图 形 学
直线的绘制首先要考虑的是绘制的质量。怎样才算高质量? 当然,看上去要象直线。 : 1. 画的直线应是直的 2. 线的端点位置应正确 3. 线的浓度应均匀 4. 直线生成的速度要快
第三章 基本图形元素的生成算法
(X1,Y1)的像素点,对应的显示缓冲器地址为: 字节地址= S + ( H / 8 ) * Y1 + ( X1 / 8 ) 的整数部分 字节内的位地址= X1 / 8 的余数 计 算 机 图 形 学
第三章 基本图形元素的生成算法
3.1.2 直线段的生成
数学上的直线是由无数个点构成的集合,显 然,光栅显示器只能近地似显示直线。对 于水平、垂直和45°斜线是可以达到较为 满意的效果的。当我们对直线进行光栅化 时,需要确定最佳逼近该直线的一组象素。 扫描转换直线段就是计算出落在直线段上 或充分靠近它的一串像素,并以此像素近 似代替原连续直线段在屏幕上显示的过程。
第三章 基本图形元素的生成算法
3.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要求:指定顶点的命令必须包含在 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等几何图元。

直线生成算法

由于只用d 的符号作判断,为了只包含整数运算, 可以用2d代替d来摆脱小数,提高效率。
中点画线法
• •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); • x=x0; y=y0; • putpixel(x, y, color); • while (x<x1) • { if (d<0) {x++; y++; d+=d2; } • else {x++; d+=d1;} • putpixel (x, y, color); • } /* while */ • } /* mid PointLine */
P2 Q
P=(xp,yp) P1
∴欲判断 M 点是在 Q 点上方还是在 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; 能否采用增量算法呢?
批注本地保存成功开通会员云端永久保存去开通
计算机地图制图
• Turbo C提供了非常丰富的图形函数, 所有 图形函数的原型均在graphics. h中,将集成 开发环境Options/Linker中的Graphics lib选 为on, 只有这样才能保证正确使用图形函数。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档