计算机图形学实验(一) Bresenham画直线和中点画圆法画圆
图形学的第一个实验,
因为老师课上的讲解原因,所以这里将一个边长为1的正方形块作为一个像素,放大后可以看出来。
先上代码,画线的:
void drawLine(node * mnode)
{
glClearColor(0.0f, 0.0f, 0.0f,0.0f);//绘图颜色为黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400,i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x,y, x+1, y+1); //绘制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
放大后的图像
然后是画圆的代码:
void drawCircle()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
//glBegin(GL_POINTS);
glBegin(GL_LINES);
glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glViewport(0, 0, 400, 400);
glColor3f(1.0, 0.0, 0.0);
int x, y;
float d;
int r = 100;
x = 0, y = r;
d = 1.25 - r;
//glVertex2i(x+r,y+r);
//glVertex2i(y+r, x+r);
//glVertex2i(-x+r, y+r);
//glVertex2i(y+r, -x+r);
//glVertex2i(x+r, -y+r);
//glVertex2i(-y+r, x+r);
//glVertex2i(-x+r, -y+r);
//glVertex2i(-y+r, -x+r);
glRectf(x+r, y+r, x +r+1, y+r+1); //绘制矩形
glRectf(y+r, x+r, y+r+ 1, x+r+1); //绘制矩形
glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //绘制矩形
glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //绘制矩形
glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //绘制矩形
glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //绘制矩形
glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //绘制矩形
glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //绘制矩形
while (x <= y)
{
if (d <= 0)
{
d += 2 * x + 3;
}
else
{
d += 2 * (x - y) + 5;
y--;
}
x++;
//cout<< x <<" "<<y<< endl;
/*glVertex2i(x + r, y + r);
glVertex2i(y + r, x + r);
glVertex2i(-x + r, y + r);
glVertex2i(y + r, -x + r);
glVertex2i(x + r, -y + r);
glVertex2i(-y + r, x + r);
glVertex2i(-x + r, -y + r);
glVertex2i(-y + r, -x + r);*/
glRectf(x + r, y + r, x + r + 1, y + r + 1); //绘制矩形
glRectf(y + r, x + r, y + r + 1, x + r + 1); //绘制矩形
glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //绘制矩形
glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //绘制矩形
glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //绘制矩形
glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //绘制矩形
glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //绘制矩形
glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //绘制矩形
}
//glEnd();
glFlush();
}
放大后的代码:
实现原理:
过各行各列像素中心构造一组网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。该算法的巧妙之处在于采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求的像素。
简单来说就是如果在中点及以下则取y,中点以上则取y+1。
中点画圆法:
完整的代码:
// ConsoleApplication2.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<gl/GLUT.H>
#include<cmath>
#include<iostream>
#include "node.h"
using namespace std;
node Line[2] = { node(0.0,0.0),node(0.0,0.0) };
int nodeNumber = 0;
bool finish = false;//已经画完
void Initial(void)//初始化函数
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//白色背景,前3个是RGB,最后是Alpha值,用来控制透明,1.0表示完全不透明
glMatrixMode(GL_MODELVIEW);//OpenGL按照三维方式来处理图像,所以需要一个投影变换将三维图形投影到显示器的二维空间中
glLoadIdentity();
gluOrtho2D(0.0, 400, 0.0, 400.0);//指定使用正投影将一个x坐标在0~200,y坐标0~150范围内的矩形坐标区域投影到显示器窗口
}
void drawLine(node * mnode)
{
glClearColor(0.0f, 0.0f, 0.0f,0.0f);//绘图颜色为黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400,i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x,y, x+1, y+1); //绘制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
void drawLine1()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = 0, y1 = 8, x2 = 50, y2 = 100;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x, y, x + 1, y + 1); //绘制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
void drawLine()
{
if (finish)
{
drawLine(&Line[0]);
finish = false;
}
}
void drawCircle()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
//glBegin(GL_POINTS);
glBegin(GL_LINES);
glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glViewport(0, 0, 400, 400);
glColor3f(1.0, 0.0, 0.0);
int x, y;
float d;
int r = 100;
x = 0, y = r;
d = 1.25 - r;
//glVertex2i(x+r,y+r);
//glVertex2i(y+r, x+r);
//glVertex2i(-x+r, y+r);
//glVertex2i(y+r, -x+r);
//glVertex2i(x+r, -y+r);
//glVertex2i(-y+r, x+r);
//glVertex2i(-x+r, -y+r);
//glVertex2i(-y+r, -x+r);
glRectf(x+r, y+r, x +r+1, y+r+1); //绘制矩形
glRectf(y+r, x+r, y+r+ 1, x+r+1); //绘制矩形
glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //绘制矩形
glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //绘制矩形
glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //绘制矩形
glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //绘制矩形
glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //绘制矩形
glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //绘制矩形
while (x <= y)
{
if (d <= 0)
{
d += 2 * x + 3;
}
else
{
d += 2 * (x - y) + 5;
y--;
}
x++;
//cout<< x <<" "<<y<< endl;
/*glVertex2i(x + r, y + r);
glVertex2i(y + r, x + r);
glVertex2i(-x + r, y + r);
glVertex2i(y + r, -x + r);
glVertex2i(x + r, -y + r);
glVertex2i(-y + r, x + r);
glVertex2i(-x + r, -y + r);
glVertex2i(-y + r, -x + r);*/
glRectf(x + r, y + r, x + r + 1, y + r + 1); //绘制矩形
glRectf(y + r, x + r, y + r + 1, x + r + 1); //绘制矩形
glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //绘制矩形
glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //绘制矩形
glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //绘制矩形
glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //绘制矩形
glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //绘制矩形
glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //绘制矩形
}
//glEnd();
glFlush();
}
void mouseClick(int btn, int state, int x, int y)
{
if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)//点击左键
{
y = 400 - y;
node temp(x, y);
if (nodeNumber<2)
{
Line[nodeNumber] = temp;
nodeNumber++;
glColor3f(1.0, 0.0, 0.0);
// glViewport(0, 0, 400, 400);
glBegin(GL_POINTS);
glVertex2d(x, y);
glEnd();
glFlush();
}
}
if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)//点击右键
{
//drawLine(&Line[0]);
finish = true;
nodeNumber = 0;
}
}
int main(int argc, char * argv[])//这是使用glut库函数进行窗口管理
{
glutInit(&argc, argv);//使用glut库需要进行初始化
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设定窗口显示模式,颜色模型和缓存,这里是RGB颜色模型和单缓存
glutInitWindowPosition(100, 100);//设定窗口的初始位置,屏幕左上角为原点,单位为像素
glutInitWindowSize(400, 400);//设定窗口的大小
glutCreateWindow("直线");//创建一个窗口,参数是窗口标题名
Initial();
glutDisplayFunc(&drawLine1);//将myDisplay指定为当前窗口的显示内容函数*/
//glutMouseFunc(mouseClick);
glutCreateWindow("圆");//创建一个窗口,参数是窗口标题名
Initial();
glutDisplayFunc(&drawCircle);//将myDisplay指定为当前窗口的显示内容函数
glutMainLoop();//使窗口框架运行起来,使显示回调函数开始工作
return 0;
}
还有一个头文件:
#pragma once
#pragma once
struct node//点结构
{
double x;
double y;
node()
{
x = 0.0;
y = 0.0;
}
~node() {}
node(double xx, double yy)
{
x = xx;
y = yy;
}
/*node & operator=(const node& a)
{
node m;
m.x = a.x;
m.y = a.y;
return m;
}*/
};
struct side//边结构
{
node a;
node b;
side(node aa, node bb)
{
a.x = aa.x;
a.y = aa.y;
b.y = bb.y;
b.x = bb.x;
}
side(int n)
{
a.x = 0;
a.y = 0;
b.x = 0;
b.y = 0;
}
side()
{
a.x = 0;
a.y = 0;
b.x = 0;
b.y = 0;
}
};
还没有评论,来说两句吧...