#include <GL/glut.h>
#include "QuadTree.h"
#include "Point.h"
#include <vector>
using std::vector;
vector<Point> Points_array;//点向量,用于存放鼠标点击屏幕的点序列
Point point;//保存当前鼠标的点击点,用于在屏幕上绘制点
int width=512,height=512; //图像的长宽,选择512,即2的9次方以方便计算
QT_Node root,*root_p;//四叉树类root,根节点,以及指向该根节点的指针
void init (void) //初始化
{
glClear(GL_COLOR_BUFFER_BIT);
}
void drawpoints() //绘制点函数,为了使点的现实更明显,采用了将一个点周围八个点统一绘制的方法
{
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POINTS);
glVertex2f(point.x-1, point.y+1);
glVertex2f(point.x, point.y+1);
glVertex2f(point.x+1, point.y+1);
glVertex2f(point.x-1, point.y);
glVertex2f(point.x, point.y);
glVertex2f(point.x+1, point.y);
glVertex2f(point.x-1, point.y-1);
glVertex2f(point.x, point.y-1);
glVertex2f(point.x+1, point.y-1);
glEnd();
}
void drawline(QT_Node *t)//绘制分割线,采用二叉树遍历的方法,判断每个节点的有效子节点数,如果大于1,则说明需要分割
{
if(t!=NULL)
{
if(t->child>1)
{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex2f(t->left_down.x,(t->left_down.y+t->right_up.y)/2);
glVertex2f(t->right_up.x, (t->left_down.y+t->right_up.y)/2);
glVertex2f((t->left_down.x+t->right_up.x)/2,t->left_down.y);
glVertex2f((t->left_down.x+t->right_up.x)/2, t->right_up.y);
glEnd();
}
drawline(t->llChild); //遍历四叉树
drawline(t->luChild);
drawline(t->ruChild);
drawline(t->rlChild);
}
}
void display(void)
{
glClearColor(0.0,0.0,0.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawpoints(); //在屏幕上绘制点
root_p->CreatTree(root_p,Points_array);//在根节点已经建立的基础上,判断计算出每个点正确的位置
//将向量中的每个点绘制到四叉树中
root_p->PostOrder(root_p); //计算每个节点的有效子节点数,并将结果赋值于节点类中的child变量中
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, w, 0.0, h);
width=w;
height=h;
}
void mouse(int button,int state,int x,int y) //对应注册鼠标事件的函数,保存取点的坐标
{
bool flag=true;
if(state==GLUT_DOWN&&button==GLUT_LEFT_BUTTON)
{
point.setPoint(x,height-y);//OpenGl窗口和计算时有一点差别,即Y轴相反,故采用height-y方式先转换
for(int i=0;i<Points_array.size();i++)
{
if(point.x==Points_array[i].x&&point.y==Points_array[i].y)
flag=false;
}
if(flag)
Points_array.push_back(point);//压点进栈
}
if(state==GLUT_DOWN&&button==GLUT_RIGHT_BUTTON)
{
drawline(root_p);//按下鼠标右键,则绘制分割线
glutPostRedisplay();
}
glutPostRedisplay();
}
int main(int argc, char** argv)//主程序
{
root.left_down.setPoint(0,0);//初始化节点的左下点
root.right_up.setPoint(width,height);//初始化节点的右上点,有这两点确定有效范围
root_p=&root;
glutInit(&argc,argv);
glutInitWindowPosition(100,100);
glutInitWindowSize(width,height);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutCreateWindow("四叉树-陈力-200626380203");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}