欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机图形学(1)——直线生成算法的实现

程序员文章站 2022-07-14 09:59:34
...

网上可以找到很多关于直线生成算法的原理的讲解,这里就不赘述了。参考书籍如下:

计算机图形学(1)——直线生成算法的实现

书上实验二的示例程序:
#include "stdafx.h"
#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,1.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;
}
 
(2)用Bresenham算法实验代码:
#include "stdafx.h"
#include <GL/glut.h>
#include <math.h>
//#include <WinGDI.h>
 
void swap_value (int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
 
void Bres_Line(int x1,int y1,int x2,int y2,int color) //Bresenham画线法
{
//setpixel(x1,y1,color); //将指定坐标处的像素设为指定的颜色
glColor3f(0.0, 0.0, 1.0);       // 蓝色
glPointSize(2.0f);
int dx=abs(x2-x1);
int dy=abs(y2-y1);
 
if(dx==0&&dy==0)
{
glBegin(GL_POINTS);
glVertex2f(x1, y1);
glEnd();
glFlush();
return;
}
 
int flag=0;
if(dx<dy) //下面将斜率变换至0<=|k|<=1之间
{
flag=1;
swap_value(&x1,&y1);
swap_value(&x2,&y2);
swap_value(&dx,&dy);
}
 
int tx=(x2-x1)>0?1:-1;
int ty=(y2-y1)>0?1:-1;
int curx=x1;
int cury=y1;
int dS=2*dy;
int dT=2*(dy-dx);
int d=dS-dx;
 
while(curx!=x2)
{
if(d<0)
d+=dS;
else
{
cury+=ty;
d+=dT;
}
 
if(flag)
//setpixel(cury,curx,color);
{
glBegin(GL_POINTS);
glVertex2f(cury, curx);
glEnd();
glFlush();
}
else
//setpixel(curx,cury,color);
{
glBegin(GL_POINTS);
glVertex2f(curx, cury);
glEnd();
glFlush();
}
curx+=tx;
}
}
 
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 (); 
 
Bres_Line(0, 0, 200, 300,1.0f); //LineDDA不接受四个参数(修改处)
 
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("直线生成算法实现");
 
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}

实验结果:

计算机图形学(1)——直线生成算法的实现 

实验提高

1)修改示例程序中的错误(修改LineDDA()函数),实现DDA算法

// CG_2_DDA算法.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include <GL/glut.h>

#include <math.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;

if(abs(dx)>=abs(dy))

m=abs(dx);          //x为计长方向

else

m=abs(dy);          //y为计长方向

    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,200,200);//课内的DDA算法函数

LineDDA(0,0,200,200);

 

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();//保证前面的opengl命令立即执行

}

 

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);//调整像素矩形,用于绘制整个窗口

//接下来三个函数用于调整绘图坐标系,左下角坐标为(00),右上角坐标为(wh

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);

}

 

int main(int argc, char *argv[])

{

glutInit(&argc,argv);//GLUT进行初始化

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设置显示方式

glutInitWindowPosition(100,100);//设置窗口在屏幕中的位置

glutInitWindowSize(400,400);//设置窗口的大小

glutCreateWindow("Hello World!");//根据前述设置的信息创建窗口,参数将被作为窗口的标题

Init();

glutDisplayFunc(myDisplay);//设置一个函数,当需要进行画图时,这个函数就会被调用

glutReshapeFunc(Reshape);

glutMainLoop();//进行一个消息循环,等待窗口关闭后才会返回

return 0;

}

 

运行结果:

计算机图形学(1)——直线生成算法的实现 

(2)Bresenham画线法

// CG_2_Bresenham画线法.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include <GL/glut.h>

#include <math.h>

 

void swap_value(int* a, int* b)

{

int temp=*a;

*a=*b;

*b=temp;

}

 

void Bres_Line(int x1,int y1,int x2,int y2)

{

glVertex2i(x1,y1);

int dx=abs(x2-x1);

int dy=abs(y2-y1);

if(dx==0&dy==0)

return;

int flag=0;

if(dx<dy)

{

flag=1;

swap_value(&x1,&y1);

swap_value(&x2,&y2);

swap_value(&dx,&dy);

}

int tx=(x2-x1)>0?1:-1;

int ty=(y2-y1)>0?1:-1;

int curx=x1;

int cury=y1;

int dS=2*dy;

int dT=2*(dy-dx);

int d=dS-dx;

while(curx!=x2)

{

if(d<0)

d+=dS;

else

{

cury+=ty;

d+=dT;

}

if(flag)

glVertex2i(cury,curx);

else

glVertex2i(curx,cury);

curx+=tx;

}

}

 

 

 

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,200);

Bres_Line(0,0,200,200);

 

 

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;

}

 

运行结果:

 

计算机图形学(1)——直线生成算法的实现