计算机图形学(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)修改示例程序中的错误(修改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);//调整像素矩形,用于绘制整个窗口
//接下来三个函数用于调整绘图坐标系,左下角坐标为(0,0),右上角坐标为(w,h)
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;
}
运行结果:
(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;
}
运行结果: