说明
其实就是BFS或者DFS都可以
代码
#include <GLUT/GLUT.h>
#include <iostream>
#include<iostream>
#include<cstdlib>
#include <queue>
using namespace std;
float wid = 400; //设置窗口的大小,约定窗口必须为正方形
float height = wid; //设置窗口的大小
int numbers = 20; //设置划分的网格的个数
float t = wid/numbers; //模拟像素下的单位1
int con [41][41];
/*
参数设置说明:
输入直线的两点A(x1,y1);B(x2,y2)
您应当确保参数范围在-400~400.且为20的倍数。
这是因为我们的单位步长为20.
*支持不同斜率
*支持两点位置颠倒
*/
struct V {
int x,y;
};
int x1 = 120,y1=80,x2 =300,y2 = 200;
int xx1 = 20,yy1=180,xx2 =300,yy2 = 200;
int xxx1 = 20,yyy1=180,xxx2 =120,yyy2 = 80;
void draw_point(float x, float y,int k_kind,int d_kind);
float translater(int x);
void swap(int &a, int &b)
{ int tmp = 0;
tmp = b;
b = a;
a = tmp; }
void bresenham(int x1, int y1,int x2, int y2){
/*
函数说明:bresenham算法部分
参数说明:与openGL已有的划线函数一样,要求用户提供的是点的起点(x1,y1)和终点(x2,y2)
为了便于观察,我们会绘制原像素下的直线。
这里的坐标要求是-1 ~ 1
*/
int k_kind = 0; //k_kind用来表示斜率的类型。0是0~1;1是1~无穷;2是0~-1;3是负无穷~-1
int d_kind =0; //d_kind用来表示dy正负的类型。
if (x1 > x2) {
swap(x1,x2);
swap(y1,y2);
}
int dx = abs(x2-x1), dy = abs(y2-y1);
if (y1 > y2) {//如果是向下的
y1 = -y1;
y2 = -y2;
d_kind = 1;
}
if (dy > dx) { //斜率介于1~无穷的,将看作坐标系变换(这里将坐标变换)。
swap(x1, y1);
swap(x2,y2);
swap(dx,dy);
k_kind = 1;
}
float d = (dy +dy -dx)*t; //令d为决策量(这里利用d = dx*w*2避免浮点运算)
float x = x1+0.0,y = y1+0.0;
draw_point(translater(x),translater(y),k_kind,d_kind); //绘制下一个点
while( x < x2){ //以x为步长
if (d < 0){
d += 2*dy*t;
}
else{
d += 2*(dy-dx)*t;
y += t; //说明应该画在上面那个位置
}
x= x + t;
cout << "saa "<< (int)x/20 <<"-- " <<(int)y/20 <<endl;
draw_point(translater(x),translater(y),k_kind,d_kind); //绘制下一个点
}
}
float translater(int x){
/*
函数说明:将像素坐标下的坐标转化为openGL坐标
参数说明:传入点像素坐标-wid-wid,返回-1~1坐标
*/
return x/wid;
}
void BFS_filling(){
queue<V> vcon;
V a;
a.x =60;
a.y = 160;
vcon.push(a);
while(!vcon.empty()){
V temp = vcon.front();
vcon.pop();
if (!con[temp.x/20][temp.y/20]) {
con[temp.x/20][temp.y/20] =1;
glPointSize(14);
glColor3f(0.0,1.0,0.0);
glBegin(GL_POINTS);
glVertex3f(translater(temp.x),translater(temp.y),0.0);
glEnd();
glFlush();
if (con[temp.x/20+1][temp.y/20]==0) {
V a;
a.x =temp.x+20;
a.y = temp.y;
vcon.push(a);
}
cout << temp.x/20 - 1<<" " << temp.y/20<<endl;
cout << con[temp.x/20-1][temp.y/20]<<endl;
if ((temp.x/20-1 )>=0&&con[temp.x/20-1][temp.y/20]==0) {
V a;
a.x =temp.x-20;
a.y = temp.y;
vcon.push(a);
}
if (con[temp.x/20][temp.y/20+1]==0) {
V a;
a.x =temp.x;
a.y = temp.y+20;
vcon.push(a);
}
if (temp.y/20-1 >=0 &&con[temp.x/20][temp.y/20-1]==0) {
V a;
a.x =temp.x;
a.y = temp.y-20;
vcon.push(a);
}
}}}
void draw_point(float x , float y, int k_kind,int d_kind){
/*
函数说明:绘制像素的点,这里将点的大小设置为17
颜色采用蓝色。
参数说明:浮点数x,y是openGl坐标系。kind是指明斜率的类型
*/
glPointSize(17);
glColor3f(0.0,0.0,1.0);
glBegin(GL_POINTS);
cout <<"k:"<<k_kind<<"d:" << d_kind << endl;
if(k_kind==0&&d_kind==1){
y = -y;
}else if (k_kind ==1 &&d_kind==1){
x= -x;
swap(x,y);
}else if (k_kind==1&&d_kind ==0){
swap(x,y);
}
int xx = x*400/20;
int yy = y*400/20;
con[xx][yy]=1;
glVertex3f(x,y,0.0);
glEnd();
glFlush();
}
void draw_line(int x1, int y1 ,int x2 , int y2){
/*
函数说明:绘制原直线
*/
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
glVertex2f(translater(x1),translater(y1)); //定点坐标范围
glVertex2f(translater(x2),translater(y2));
glEnd();
glFlush();
}
void grid(){
/*
函数说明:绘制网格为了便于将真实的像素pixel转化为我们模拟的像素
*/
glClearColor(0, 0, 0, 0);//这是设置背景色,必须要在glclear之前调用
glClear(GL_COLOR_BUFFER_BIT);
//画直线
int wid_number = numbers;
int hei_number = numbers;
float delta_wid = wid / wid_number;
float delta_hei = height / hei_number;
glColor3f(1.0,1.0,0);
for (int i = 1; i < 40 ; i ++ ) {
glBegin(GL_LINES);
glVertex2f(-1+i*delta_hei/height, -1);
glVertex2f(-1+i*delta_hei/height, 1);
glVertex2f(-1,-1+i*delta_hei/height);
glVertex2f(1,-1+i*delta_hei/height);
glEnd();
glFlush();
}
glColor3f(1.0,0,0);
glBegin(GL_LINES); //绘制坐标系,便于观察
glVertex2f(-1,0);
glVertex2f(1,0);
glVertex2f(0,-1);
glVertex2f(0,1);
glEnd();
glFlush();
draw_line(x1, y1, x2, y2);
draw_line(xx1, yy1, xx2, yy2);
draw_line(xxx1, yyy1, xxx2, yyy2);
//刷新缓冲,保证绘图命令能被执行
bresenham(x1, y1,x2,y2);
bresenham(xx1, yy1,xx2,yy2);
bresenham(xxx1, yyy1,xxx2,yyy2);
BFS_filling();
}
int main(int argc, char *argv[]) {
for (int i = 0; i < 41; i++) {
for (int j = 0; j< 41; j++) {
con[i][j] = 0;
}
}
//初始化GLUT library
glutInit(&argc, argv);
//对窗口的大小进行初始化
glutInitWindowSize(700,700);
glutInitWindowPosition(300,200);
// 设置窗口出现的位置
//glutInitWindowPosition(int x, int y);
glutInitDisplayMode(GLUT_RGBA);
glutCreateWindow("class16_hw1");
glutDisplayFunc(&grid);
glutMainLoop();
return 0;
}