一、实验实习目的及要求
目的:
熟悉光栅图形学中的相关算法
要求:
1、利用OpenGL点绘制函数直线和区域。
2、采用直线扫描算法绘制一条线段,直线由离散点组成。
3、利用区域填充算法绘制多边形区域,区域由离散点组成
二、实验实习设备(环境)及要求(软硬件条件)
设备:PC机
操作系统:win7或以上
编译软件:VC6.0、vs2010等
三、实验实习内容与步骤
- 初始化
- 加入中点扫描算法和区域扫描算法
- 设置窗口值
- 调用函数
- 结束程序
四、实验实习过程或算法(源程序、代码)
第一个代码:
#include <GL/glut.h>
#include <math.h>
void init()
{ glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-500,500,-500, 500);
glMatrixMode(GL_MODELVIEW);
}
void lineWithDDA(GLint x0, GLint y0, GLint xn, GLint yn)
{ GLfloat dx = xn - x0;
GLfloat dy = yn - y0;
GLint steps = 0;
GLfloat deltaX = 0;
GLfloat deltaY = 0;
GLfloat x = x0;
GLfloat y = y0;
if ( abs(dx) > abs(dy)){
steps = abs(dx);}
else{
steps = abs(dy);}
deltaX = (GLfloat)dx / (GLfloat)steps;
deltaY = (GLfloat)dy / (GLfloat)steps;
glColor3f(1.0, 0.0, 1.0);
int b=1;
steps = steps / b;
deltaX = deltaX * b;
deltaY = deltaY * b;
glBegin(GL_POINTS);
for (GLint i = 1; i <= steps; i++){
x += deltaX;
y += deltaY;
glVertex2i(x, y);}
glEnd();
}
void my(){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
glLineWidth(1);
glBegin(GL_LINES);
glColor3f(0.0, 0.0, 0.0);
glVertex2i(0, -500);
glVertex2i(0, 500);
glVertex2i(-500, 0);
glVertex2i(500, 0);
glEnd();
lineWithDDA(-300,-100, 500, 500);
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("Bresenham Draw Line");
init();
glutDisplayFunc(my);
glutMainLoop();
return 0;
}
第二个代码:
#include "gl/glut.h"
#include "windows.h"
const int POINTNUM = 6; //多边形点数.
/******定义结构体用于活性边表AET和新边表NET*******/
typedef struct XET
{
float x;
float dx, ymax;
XET* next;
}AET, NET;
/******定义点结构体point***********/
struct point
{
float x;
float y;
}
polypoint[POINTNUM] = { 250, 50, 550, 150, 550, 400, 100, 350, 100, 100, 120, 30 };//多边形顶点
void PolyScan()
{
/******计算最高点的y坐标(扫描到此结束)******* /
/*******初始化AET表*******/
AET *pAET = new AET;
pAET->next = NULL;
/******初始化NET表*******/
int MaxY = 0;
int i;
for (i = 0; i<POINTNUM; i++)
if (polypoint[i].y>MaxY)
MaxY = polypoint[i].y;
NET *pNET[1024];
for ( i = 0; i <= MaxY; i++)
{
pNET[i] = new NET;
pNET[i]->next = NULL;
}
glClear(GL_COLOR_BUFFER_BIT); //赋值的窗口显示.
glColor3f(0.0, 0.0, 1.0); //设置直线的颜色蓝色
glBegin(GL_POINTS);
for (i = 0; i <= MaxY; i++)
{
for (int j = 0; j<POINTNUM; j++)
if (polypoint[j].y == i)
{ //一个点跟前面的一个点形成一条线段,跟后面的点也形成线段
if (polypoint[(j - 1 + POINTNUM) % POINTNUM].y>polypoint[j].y)
{
NET *p = new NET;
p->x = polypoint[j].x;
p->ymax = polypoint[(j - 1 + POINTNUM) % POINTNUM].y;
p->dx = (polypoint[(j - 1 + POINTNUM) % POINTNUM].x - polypoint[j].x) / (polypoint[(j - 1 + POINTNUM) % POINTNUM].y - polypoint[j].y);
p->next = pNET[i]->next;
pNET[i]->next = p;
}
if (polypoint[(j + 1 + POINTNUM) % POINTNUM].y>polypoint[j].y)
{
NET *p = new NET;
p->x = polypoint[j].x;
p->ymax = polypoint[(j + 1 + POINTNUM) % POINTNUM].y;
p->dx = (polypoint[(j + 1 + POINTNUM) % POINTNUM].x - polypoint[j].x) / (polypoint[(j + 1 + POINTNUM) % POINTNUM].y - polypoint[j].y);
p->next = pNET[i]->next;
pNET[i]->next = p;
}
}
};
for (i = 0; i <= MaxY; i++)
{
//计算新的交点x,更新AET
NET *p = pAET->next;
while (p)
{
p->x = p->x + p->dx;
p = p->next;
}
//更新后新AET先排序
//断表排序,不再开辟空间
AET *tq = pAET;
p = pAET->next;
tq->next = NULL;
while (p)
{
while (tq->next && p->x >= tq->next->x)
tq = tq->next;
NET *s = p->next;
p->next = tq->next;
tq->next = p;
p = s;
tq = pAET;
}
//(改进算法)先从AET表中删除ymax==i的结点
AET *q = pAET;
p = q->next;
while (p)
{
if (p->ymax == i)
{
q->next = p->next;
delete p;
p = q->next;
}
else
{
q = q->next;
p = q->next;
}
}
//将NET中的新点加入AET,并用插入法按X值递增排序
p = pNET[i]->next;
q = pAET;
while (p)
{
while (q->next && p->x >= q->next->x)
q = q->next;
NET *s = p->next;
p->next = q->next;
q->next = p;
p = s;
q = pAET;
};
p = pAET->next;
while (p && p->next)
{
for (float j = p->x; j <= p->next->x; j++)
glVertex2i(static_cast<int>(j), i);
p = p->next->next;//考虑端点情况
}
}
glEnd();
glFlush();
}
void init(void)
{
glClearColor(0.0, 1.0, 0.0, 0.0);//窗口的背景颜色设置为绿色
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 600.0, 0.0, 450.0);
}
int main(int argc,char* argv)
{
glutInit(&argc, &argv); //I初始化 GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //设置显示模式:单个缓存和使用RGB模型
glutInitWindowPosition(50, 100); //设置窗口的顶部和左边位置
glutInitWindowSize(400, 300); //设置窗口的高度和宽度
glutCreateWindow("An Example OpenGL Program"); //创建显示窗口
init(); //调用初始化过程
glutDisplayFunc(PolyScan); //图形的定义传递给我window.
glutMainLoop(); //显示所有的图形并等待
return 0;
}
五、实验实习结果分析和(或)源程序调试过程
1、
2、