?? seripinski.cpp
字號:
#include <windows.h>
#include <gl/glut.h>
#include <math.h>
const double PI=3.1415926;
const float MIN_LEN = 0.0001;
const float LEN = 0.6;
const float g_x1=-LEN, g_y1=-LEN, g_x2=0, g_y2=LEN, g_x3=LEN, g_y3=-LEN;
/// 窗口寬度
int g_width=400;
/// 窗口高度
int g_height=300;
///鼠標器左鍵是否按下
bool mouse_button_pressed=false;
///記錄鼠標器位置
int mouse_x;
///記錄鼠標器位置
int mouse_y;
///旋轉的緯度
float theta=0;
///旋轉的經度
float phi=0;
/**
鼠標按鈕回調函數
*/
void mouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
//如果鼠標器左鍵按下,mouse_button_pressed置位
//并記錄光標位置
{
mouse_button_pressed = true;
mouse_x = x;
mouse_y = y;
}
else
{
mouse_button_pressed = false;
}
}
}
/**
鼠標運動處理函數
*/
void motion(int x, int y)
{
if(mouse_button_pressed)
{
theta -= y-mouse_y; //根據鼠標器的移動改變旋轉的緯度
if(theta<0) theta = 0; //限制緯度在0到180度之間
if(theta>180) theta = 180;
phi += x-mouse_x; //根據鼠標器的移動改變旋轉的經度
if(phi<0) phi+=360; //限制經度在0到360度之間
if(phi>360) phi-=360;
mouse_x = x; //更新記錄的鼠標器位置
mouse_y = y;
glutPostRedisplay();
//通知系統:窗口需要刷新
}
}
/**
點類
*/
class point {
public:
float x;
float y;
public:
point(float _x, float _y) {x=_x;y=_y;}
point(point& p) {x=p.x; y=p.y;}
point middle(point& p2) {return point((x+p2.x)/2, (y+p2.y)/2);}
float between(point& p2) {return (x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y);}
};
/**
繪制Seripinski墊票
三點坐標為a(x1,y1), b(x2,y2), c(x3,y3)
*/
void seripinski(point& a, point& b, point& c)
{
if (a.between(b) < MIN_LEN && b.between(c) < MIN_LEN) return;
//繪制三角形
glBegin(GL_LINE_LOOP);
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
glVertex2f(c.x, c.y);
glEnd();
//遞歸繪制三個角
seripinski(a, a.middle(b), a.middle(c));
seripinski(a.middle(b), b, b.middle(c));
seripinski(a.middle(c), b.middle(c), c);
}
/**
\b 主處理回調函數,每當需要重畫時由OpenGL庫調用
\b 該函數功能是調用seripinski,繪制seripinski墊票
\b 三點坐標分別為a(10, g_height-10),b(g_width/2,g_height-10),c(g_width-10, 10)
*/
void main_display_loop(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //刷新背景
glMatrixMode (GL_PROJECTION); //設置矩陣模式為投影矩陣
glLoadIdentity(); //初始化投影矩陣
glOrtho(-1,1,-1,1,-1,1); //設置平行投影的投影矩陣
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(phi,0,1,0); //繞y軸旋轉OCS,旋轉的角度為phi
glRotatef(theta,1,0,0); //繞x軸旋轉OCS,旋轉的角度為theta
glColor3f(1, 0, 0);
glPushMatrix();
glTranslatef(0, 0, -0.4);
seripinski(point(g_x1, g_y1), point(g_x2, g_y2), point(g_x3, g_y3));
glPopMatrix();
glColor3f(0, 1, 0);
glPushMatrix();
glTranslatef(0, 0, 0.4);
seripinski(point(g_x1, g_y1), point(g_x2, g_y2), point(g_x3, g_y3));
glPopMatrix();
glColor3f(0, 0, 1);
glPushMatrix();
glTranslatef(0.4, 0, 0);
glRotatef(90, 0, 1, 0);
seripinski(point(g_x1, g_y1), point(g_x2, g_y2), point(g_x3, g_y3));
glPopMatrix();
glColor3f(0, 0.3, 0.5);
glPushMatrix();
glTranslatef(-0.4, 0, 0);
glRotatef(90, 0, 1, 0);
seripinski(point(g_x1, g_y1), point(g_x2, g_y2), point(g_x3, g_y3));
glPopMatrix();
glFlush(); //更新窗口
glutSwapBuffers();
}
/**
OPENGL 特性初始化函數
*/
init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(0,0,0,1);
glClearDepth(1);
glColor3f(0, 0, 1);
}
/// 主函數
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGBA);
glutInitWindowSize(g_width, g_height);
glutCreateWindow("OpenGL");
init();
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc(main_display_loop);
glutMainLoop();
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -