Язык программирования:
C/C++
Среда программирования:
Visual Studio 2010
#include "stdafx.h" #include <glut.h> #include <math.h> float WinWidth = 600.0; float WinHeight = 400.0; float max_a = 100.0; //макс. диагональ квадрата float min_a = 50.0; //мин. диагональ квадрата int angle = 90; //макс. угол поворота квадрата по модулю int angstep = 3; //шаг поворота bool *DirRot; //направление вращения фигуры bool *Dir; //направление движения ряда int *Angle; //храним текущий угол поворота [-angle;angle] bool *IsRot; //разрешено ли вращение? int x_el = int(WinWidth/max_a); //кол-во эл. по горизонтали int y_el = int(WinHeight/max_a);//кол-во эл. по вертикали void Display() { glClear(GL_COLOR_BUFFER_BIT); //заливка фона for(int i=0; i<y_el; i++) { //строка for(int j=0; j<x_el; j++) { //столбец int tmp=i*x_el+j; glPushMatrix(); glTranslatef(max_a*(j+1.0/2),max_a*(i+1.0/2),0.0); //сдвиг начала координат glRotatef(Angle[tmp],0.0,0.0,1.0); //поворот glScalef((max_a-(max_a-min_a)*abs(Angle[tmp])/angle)/max_a, (max_a-(max_a-min_a)*abs(Angle[tmp])/angle)/max_a, 1.0); //масштабируем диагональ квадрата glColor3ub(0,0,0); //цвет отрисовки glBegin(GL_QUADS); //рисуем фигуру glVertex2f(0.0,-max_a/2); glVertex2f(-max_a/2,0.0); glVertex2f(0.0,max_a/2); glVertex2f(max_a/2,0.0); glEnd(); glPopMatrix(); if(IsRot[tmp]) { //если можно вращать дальше - делаем это if(DirRot[tmp]) Angle[tmp]+=angstep; else Angle[tmp]-=angstep; } } } glutSwapBuffers(); //отрисовка изображения } void Timer(int value) { for(int i=0; i<y_el; i++) { //строка for(int j=0; j<x_el; j++) { //столбец int tmp=i*x_el+j; if(IsRot[tmp]) { if(Angle[tmp]>= angle || //проверяем не вышли ли мы за границы Angle[tmp]<=-angle || //[-angle;angle] ((Angle[tmp]>=0&& Angle[tmp]<angstep&& DirRot[tmp]) || (-Angle[tmp]>=0&&-Angle[tmp]<angstep&&!DirRot[tmp]))) { //или откатились в ноль IsRot[tmp]=false; //запрещаем фигуре вращаться if(Angle[tmp]>=angle) { Angle[tmp]=angle; //корректируем угол DirRot[tmp]=false; //движение против часовой стрелки } else if(Angle[tmp]<=-angle) { Angle[tmp]=-angle; DirRot[tmp]=true; //движение по часовой стрелке } else Angle[tmp]=0; if(j==0&&!Dir[i]) Dir[i]=true; //движемся вправо else if(j==x_el-1&&Dir[i]) Dir[i]=false;//движемся влево else if(Dir[i]) tmp=i*x_el+j+1; else tmp=i*x_el+j-1; IsRot[tmp]=true; //разрешаем движение следующей фигуры в текущем ряду if(DirRot[tmp]) Angle[tmp]+=angstep; else Angle[tmp]-=angstep; if(i>0) {//проверяем доступен ли ряд на уровень ниже for(int g=0; g<x_el; g++) { //если есть активные элементы, то... if(IsRot[(i-1)*x_el+g]) break; //ничего не делаем if(g==x_el-1) { //а если нет, то... tmp=(i-1)*x_el+j; IsRot[tmp]=true; //разрешаем вращение указанному элементу if(DirRot[tmp]) Angle[tmp]+=angstep; else Angle[tmp]-=angstep; } } } if(i<y_el-1) {//проверяем доступен ли ряд на уровень выше for(int g=0; g<x_el; g++) { if(IsRot[(i+1)*x_el+g]) break; if(g==x_el-1) { tmp=(i+1)*x_el+j; IsRot[tmp]=true; if(DirRot[tmp]) Angle[tmp]+=angstep; else Angle[tmp]-=angstep; } } } } } } } glutPostRedisplay(); //вызов Display() glutTimerFunc(10,Timer,0); //установка таймера } void Initialize() { DirRot = new bool[x_el*y_el]; Angle = new int [x_el*y_el]; IsRot = new bool[x_el*y_el]; Dir = new bool[y_el]; for(int i=0; i<y_el; i++) { //строка Dir[i]=true; for(int j=0; j<x_el; j++) { //столбец int tmp=i*x_el+j; Angle[tmp]=0; IsRot[tmp]=false; if((i+j)%2==0) DirRot[tmp]=true; else DirRot[tmp]=false; } } IsRot[(y_el-1)*x_el+0]=true; //указываем квадрат, с которого начинаем вращение if(DirRot[(y_el-1)*x_el+0]) Angle[(y_el-1)*x_el+0]=angstep; else Angle[(y_el-1)*x_el+0]=-angstep; glClearColor(1.0, 1.0, 1.0, 1.0); //цвет фона glMatrixMode(GL_PROJECTION); //работа с проекционной матрицей glLoadIdentity(); //загрузка единичной матрицы gluOrtho2D(0.0, WinWidth, 0.0, WinHeight); //определяем двухмерную ортографическую проекцию glMatrixMode(GL_MODELVIEW); //работа с модельно-видовой матрицей } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(WinWidth, WinHeight); glutInitWindowPosition(100, 200); glutCreateWindow("DDFellow"); glutDisplayFunc(Display); glutTimerFunc(0,Timer,0); Initialize(); glutMainLoop(); delete[]DirRot; DirRot=NULL; delete[]Angle; Angle =NULL; delete[]Dir; Dir =NULL; delete[]IsRot; IsRot =NULL; return 0; }
Прикрепленный файл | Размер |
---|---|
kontrolskiy_ddfellow.zip | 158.75 кб |