Новичок
Профиль
Группа: Участник
Сообщений: 48
Регистрация: 20.2.2012
Репутация: нет Всего: нет
|
Разобравшись с "морфингом" квадрата в пятиугольник, пришло время нарисовать так называемое "окно", состоящее из 3х прямоугольников, но при этом они вместе формируют "зеркально написанную букву С", в которой фигура, при движении должна показывать только в этом окне. Алгоритм использовал Коэна-Сазерленда(привет википедия!), с дальнейшими изменениями. Правда пока что-то не очень получается, т.к. на вид, код и правилен (в отладчике считается все правильно). Но получается, что при запуске приложения рисует только "окно", а двигающийся объект, проходящий через это окно - нет. Прощу помощи и наставления на верный путь. П.С. Заранее извиняюсь за быдлокод Собственно сам код: | Код | const int width=800, height=800; //Задаем ширину и высоту окна float coordsline[2];
//Отрисовка многоугольника void DrawPolygon(float X[], float Y[], float F[], float S[], float T[]) { int k,l,ResAnalise; static float tmp1[2],tmp2[2]; glBegin(GL_LINE_LOOP); glColor3f(0.0f, 1.0f, 0.0f); //for(k=0;k<5;k++) // glVertex2f(X[k],Y[k]); for(k=1;k<=5;k++) { if(k<=4) { tmp1[0]=X[k-1]; tmp1[1]=Y[k-1]; tmp2[0]=X[k]; tmp2[1]=Y[k]; } else { tmp1[0]=X[0]; tmp1[1]=Y[0]; tmp2[0]=X[4]; tmp2[1]=Y[4]; } for(l=0;l<=2;l++) { switch(l) { case 0: { ResAnalise=KohenSutherland(F,tmp1,tmp2); if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]); break; } case 1: { ResAnalise=KohenSutherland(S,tmp1,tmp2); if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]); break; } case 2: { ResAnalise=KohenSutherland(T,tmp1,tmp2); if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]); break; } } } } glEnd(); }
//Отрисовка окна void DrawRectangles(float F[], float S[], float T[]) { glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex2f(F[0],F[2]); glVertex2f(F[0],F[3]); glVertex2f(F[1],F[3]); glVertex2f(F[1],T[2]); glVertex2f(T[0],T[2]); glVertex2f(T[0],T[3]); glVertex2f(S[0],T[3]); glVertex2f(S[0],F[2]); glEnd(); }
//Определение положения точки //1 ~ 0001 //2 ~ 0010 //4 ~ 0100 //8 ~ 1000 static int LineCode(float Square[], float x, float y) { int code=0; if(x<Square[0]) code+=1; else if(x>Square[1]) code+=2; if(y<Square[2]) code+=4; else if(y>Square[3]) code+=8; return code; }
//Алгоритм Коэна-Сазерленда int KohenSutherland(float F[4], float crdA[2], float crdB[2]) { int code_a, code_b, code; //проверяем на каждой части фигуры(т.к. состоит из 3ех прямоугольников) //получаем коды положений точек прямой code_a=LineCode(F,crdA[0],crdA[1]); code_b=LineCode(F,crdB[0],crdB[1]); //пока одна из точек отрезка вне прямоугольника... while(code_a | code_b) { //если обе точки с одной стороны прямоугольника, то отрезок не пересекает прямоугольник if(code_a & code_b) return -1; //в противном случае выбираем точку c с ненулевым кодом if(code_a) { code=code_a; coordsline[0]=crdA[1]; coordsline[1]=crdA[1]; } else { code=code_b; coordsline[0]=crdB[1]; coordsline[1]=crdB[1]; } //если crdline[] левее F[], то передвигаем crdline[] на прямую x = F[0] if(code & 1) { coordsline[1]+=(crdA[1]-crdB[1])*(F[0]-coordsline[0])/(crdA[0]-crdB[0]); coordsline[0]=F[0]; } //если crdline[] правее F[], то передвигаем crdline[] на прямую x = F[1] else if(code & 2) { coordsline[1]+=(crdA[1]-crdB[1])*(F[1]-coordsline[0])/(crdA[0]-crdB[0]); coordsline[0]=F[1]; } //если crdline[] ниже F[], то передвигаем crdline[] на прямую y = F[2] else if (code & 4) { coordsline[0]+=(crdA[0]-crdB[0])*(F[2]-coordsline[1])/(crdA[1]-crdB[1]); coordsline[1]=F[2]; } //если crdline[] выше F[], то передвигаем crdline[] на прямую y = F[3] else if (code & 8) { coordsline[0]+=(crdA[0]-crdB[0])*(F[3]-coordsline[1])/(crdA[1]-crdB[1]); coordsline[1]=F[3]; } //обновляем коды положений точек прямой if(code==code_a) code_a=LineCode(F,crdA[0],crdA[1]); else code_b=LineCode(F,crdB[0],crdB[1]); } return 0; }
//Главная функция, отвечающая за отображение фигур, точек, и т.д. void display() { static int i,j; //Шаг перемещения static float deltaX[5],deltaY[5]; static float coords[4]; //Начальные и конечные координаты перемещения фигуры float StartX[5]={-4.5, -4.5, -3.0, -3.0, -3.0}; float StartY[5]={ 1.0, 2.5, 2.5, 2.5, 1.0}; float EndX[5]={ 4.5, 4.9, 3.7, 2.5, 2.9}; float EndY[5]={-2.3, -0.9, -0.2, -0.9, -2.3}; //Отсекающее окно, состоящее из 3х прямоугольников: {Xл,Xп,Yн,Yв} float FirstRectangle[4]={-2.0, 1.0, 1.5, 2.5}; float SeconRectangle[4]={ 0.0, 1.0, -0.5, 2.5}; float ThirdRectangle[4]={-2.0, 1.0, -1.5,-0.5};
//Отрисовка окна glClear(GL_COLOR_BUFFER_BIT); DrawRectangles(FirstRectangle,SeconRectangle,ThirdRectangle); glFlush();
//определяем дельты for(i=0;i<5;i++) { deltaX[i]=(EndX[i]-StartX[i])/30; deltaY[i]=(EndY[i]-StartY[i])/30; } //Полиморфинг фигуры: квадрат -> пятиугольник for(i=0;i<=30;i++) { glFinish(); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //закоментить-включить шлейф DrawPolygon(StartX,StartY,FirstRectangle,SeconRectangle,ThirdRectangle); for(j=0;j<5;j++) { StartX[j]=StartX[j]+deltaX[j]; StartY[j]=StartY[j]+deltaY[j]; } Sleep(50); glutPostRedisplay(); } }
//Запуск GLUT как консолльное приложение int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(width,height); glutInitWindowPosition(0,0); glutCreateWindow("Test"); glOrtho(-5.0, 5.0, -5.0, 5.0, -1, 1); glutDisplayFunc(display); glutMainLoop(); return 0; }
|
Это сообщение отредактировал(а) Relrin - 28.2.2012, 18:37
|