Similar presentations:
Технології програмування КС (лекція 4)
1.
Технології програмування КСлекція 4 (частина 2)
Проф. Цимбал О.М., кафедра ТАВР,
ХНУРЕ, Харків, Україна
2.
Матричні перетворення у OpenGL (обертання)Обертання об’єктів здійснюється за допомогою команди glRotate*():
void glRotate [f d] (GLtype angle, GLtype x, GLtype y, GLtype z);
обертання на кут angle здійснюється навколо вектора, спрямованого з центру системи
координат у точку (x, y, z). Виконання команди повертає усі об’єкти.
Припустимо, що у OpenGL-програмі у залежності від значення кута відбувається
обертання прямокутника навколо осі X :
glLineWidth(2.0);
glBegin(GL_LINES);
// визначення осей координат
glColor3f(1.0,0.0,0.0);
glVertex3f(25.0f,0.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f);//вісьX
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0f,25.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f);//вісьY
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0f,0.0f,25.0f); glVertex3f(0.0f,0.0f,0.0f);//вісьZ
glEnd();
glColor3f(0.0,0.0,1.0);
glRotatef(30*i,1,0,0); // обертання навколо X з кроком 30
glRectf(3.0,3.0,6.0,6.0); // відображення прямокутника
3.
Матричні перетворення у OpenGL (паралельний переніс)Паралельне об’єктів здійснюється командою glTranslate*():
void glTranslate [f d] (GLtype x, GLtype y, GLtype z);
Здійснюється перенесення об’єкта на відстань x вздовж осі X, y – вздовж осі Y, z – вздовж осі Z.
glLineWidth(2.0)
glBegin(GL_LINES);
glColor3f(1.0,0.0,0.0);
glVertex3f(25.0f,0.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glColor3f(0.0,1.0,0.0);
glVertex3f(0.0f,25.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0f,0.0f,25.0f);
glVertex3f(0.0f,0.0f,0.0f);
glEnd();
glColor3f(0.0,0.0,1.0);
glTranslatef(-10+i,0,0); // перенесення вздовж осі X
glRectf(3.0,3.0,6.0,6.0);
4.
Матричні перетворення у OpenGL (зміна масштабу)Масштабування розмірів об’єктів вздовж визначених координатних осей здійснюється
функцією glScale*():
void glScale [f d] (GLtype x, GLtype y, GLtype z);
Під час виконання перерахованих команд перетворення об’єктів OpenGL здійснює
перемноження поточної матриці (M) на відповідну матрицю обертання (R) або перенесення (T)
чи масштабування (S) і розміщує результат (M · R, M · T або M · S) замість поточної матриці.
Якщо у програми, описаної для обертання та трансляції, додати рядок:
glScalef(0.5*i,0.5*i,1.0);
5.
Матричні перетворення у OpenGL. ФункціїДля перегляду об’єктів з певної точки призначена команда gluLookAt() :
void gluLookAt (GLdouble eyex, GLdouble eyey, GLdouble eyez
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz);
Де: (eyex, eyey, eyez) - точку спостереження; (centerx, centery, centerz) - контрольна точку до якої
спрямовується камера; точка (upx, upy, upz) характеризує вектор верхнього напряму зони видимості.
Для роботи слід обрати точку спостереження, з якої отримується необхідний вид. Контрольна точка
зазвичай знаходиться приблизно посередині сцени. Встановлення напряму вгору (Up-vector) інколи
може викликати певні складнощі і залежатиме від положення самого об’єкта.
Матричні стеки є дуже корисним способом побудови ієрархічних комп’ютерних моделей.
Усі матричні операції, описані до сих пір (glLoadMatrix(), glMultMatrix(), glLoadIdentify()), взаємодіють з
поточною матрицею, тобто з верхньою матрицею стека.
Операції з матричним стеком забезпечуються командами glPushMatrix() та glPopMatrix():
void glPushMatrix(void); // додає поточну матрицю у вершину стека
void glPopMatrix(void); // видаляє верхівку стека – координатну матрицю певного стану.
Обидві команди доречно використовувати під час побудови складених об’єктів OpenGL-програм.
6.
Матричні перетворення у OpenGL - Aux (приклад з шасі)void CMainWin::OnChassis(void)
{ // основа шасі - прямокутник
glPushMatrix(); // запам’ятати СК
glRotatef(90.0,1.0,0.0,0.0);//поворот СК
glColor3f(0.0,0.5,1.0);
glRecti(0,0,6,6); // площина шасі
glPopMatrix(); // відновити СК
// колеса шасі
glPushMatrix(); // запам’ятати СК
glColor3f(1.0,0.5,0.0);
auxWireTorus(0.5,1.0); // колесо 1
glTranslatef(6.0,0.0,0.0); // перехід
auxWireTorus(0.5,1.0); // колесо 2
glTranslatef(0.0,0.0,6.0); // перехід
auxWireTorus(0.5,1.0); // колесо 3
glTranslatef(-6.0,0.0,0.0); // перехід
auxWireTorus(0.5,1.0); // колесо 4
glPopMatrix(); // відновити СК
}
7.
void OnChassis(void){ // основа шасі - прямокутник
glPushMatrix(); // запам’ятати СК
glRotatef(90.0, 1.0, 0.0, 0.0);//поворот СК
glColor3f(0.0, 0.5, 1.0);
glRecti(0, 0, 6, 6);
// площина шасі
glPopMatrix();
// відновити СК
// колеса шасі
glPushMatrix(); // запам’ятати СК
glColor3f(1.0, 0.5, 0.0);
glPushMatrix(); // запам’ятати СК
glRotatef(index, 0.0, 0.0, 1.0);
glutWireTorus(0.5, 1.0, 10, 10); // wheel1
glPopMatrix(); // відновити СК
glTranslatef(6.0, 0.0, 0.0); // перехід
glPushMatrix(); // запам’ятати СК
glRotatef(index, 0.0, 0.0, 1.0);
glutWireTorus(0.5, 1.0, 10, 10); // wheel2
glPopMatrix(); // відновити СК
glTranslatef(0.0, 0.0, 6.0); // перехід
glPushMatrix(); // запам’ятати СК
glRotatef(index, 0.0, 0.0, 1.0);
glutWireTorus(0.5, 1.0, 10, 10); // wheel3
glPopMatrix(); // відновити СК
glTranslatef(-6.0, 0.0, 0.0); // перехід
glPushMatrix(); // запам’ятати СК
glRotatef(index, 0.0, 0.0, 1.0);
glutWireTorus(0.5, 1.0, 10, 10); // wheel4
glPopMatrix(); // відновити СК
glPopMatrix(); // відновити СК
}
Матричні перетворення у
OpenGL Glut (приклад з шасі)
8.
Матричні перетворення у OpenGL (приклад з ракетою)void CMainWin::OnRocket(void)
{glPushMatrix();
glScalef(0.3,0.3,0.3);
glPushMatrix();// запам'ятати положення основи ракети
glColor3f(0.0,0.0,1.0);
glTranslatef(0.0,-1.0,0.0);
auxWireCylinder(1.5,11.0);// параметри - радіус, висота
glTranslatef(0.0,-10.0,0.0); // перехід до верхівки циліндра
glRotatef(90.0,1.0,0.0,0.0);// поворот конуса на 90 осі Х
auxWireCone(1.5,3.0);// параметри - радіус, висота
glPopMatrix();// повертаємося до основи ракети
glPushMatrix();
for(int i=0;i<4;i++) // цикл із стабілізаторами
{
glRotatef(90.0*i,0.0,1.0,0.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES); // стабілізатор
glVertex3f(1.5f,0.0f,0.0f); glVertex3f(3.5f,0.0f,0.0f);
glVertex3f(1.5f,-3.0f,0.0f);
glEnd();
}
glPopMatrix(); glPopMatrix();
}
9.
Матричні перетворення у OpenGL (приклад з ракетою glu/glut)void OnRocket()
{glPushMatrix();
glScalef(0.3, 0.3, 0.3);
glPushMatrix();// запам'ятати положення основи ракети
glColor3f(0.0, 0.0, 1.0);
glRotatef(90.0, 1.0, 0.0, 0.0);// поворот конуса на 90 осі Х
gluCylinder(gluNewQuadric(), 1.5, 1.5, 10.0, 10, 10); // base
glTranslatef(0.0, 0.0, 10.0); // перехід до верхівки циліндра
glutSolidCone(1.5, 3.0, 10, 10);
glPopMatrix();// повертаємося до основи ракети
glPushMatrix();
for (int i = 0; i < 4; i++)// цикл із стабілізаторами
{glRotatef(90.0 * i, 0.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLES); // стабілізатор
glVertex3f(1.5f, 0.0f, 0.0f); glVertex3f(3.5f, 0.0f, 0.0f);
glVertex3f(1.5f, -3.0f, 0.0f);
glEnd();
}
glPopMatrix();
glPopMatrix();
}
10.
Матричні перетворення у OpenGL (приклад з ракетою)// приклад із використаням списку
GLuint stab; // оголошення списку
stab=glGenLists(1); // генерація id
glNewList(stab,GL_COMPILE); // формув. списку
glBegin(GL_TRIANGLES);
glColor3f(1.0,0.0,0.0); glVertex3f(1.5f,0.0f,0.0f);
glVertex3f(3.5f,0.0f,0.0f); glVertex3f(1.5f,-3.0f,0.0f);
glEnd();
glEndList(); // кінець списку
glPushMatrix();
for(int i=0;i<4;i++)
{glRotatef(90.0*i,0.0,1.0,0.0);
glColor3f(1.0,0.0,0.0);
glCallList(stab);// виклик списку – побудова
крила
}
glPopMatrix();
// копіювання об’єктів (заданих OnRocket())
// виклик із основної частини програми
glPushMatrix();
OnRocket();
glTranslatef(2.5,0.0,0.0);OnRocket();
glTranslatef(-5.0,0.0,0.0);OnRocket();
glPopMatrix();
11.
Матричні перетворення у OpenGL (приклад із роботом)void CMainWin::OnRobot(void) // початок
{glPushMatrix();
glTranslatef(0.0,-3.0,0.0);// початкове переміщення сцени
glRotatef(360.0*vspos/100,0,1,0); // 3D-обертання навколо осі Y
glRotatef(180,0,0,1); // початковий поворот сцени на 180 градусів навколо осі Z
glLineWidth(2.0);
glPushMatrix();// запам'ятаймо положення основи робота
glRotatef(90.0,1.0,0.0,0.0);// повертаємо конус на 90 градусів навколо осі X
glColor3f(0.0,0.0,1.0);
auxWireCone(1.5,1.0);// перший параметр - радіус, другий - довжина
glPopMatrix();// повертаємося до основи робота
glTranslatef(0.0,-1.0,0.0);// змінимо висоту на -1.0 вздовж осі Y
glColor3f(0.0,0.5,0.5);
auxWireCylinder(0.6,4.0);// будуємо циліндр - колону робота
glPushMatrix();// запам'ятаймо положення кінця циліндра
// Циліндр кріплення плеча розвертається на 90 градусів навколо осі X
glTranslatef(0.0,-3.0,0.0);// переміщення у кінець колони
glRotatef(90.0,1.0,0.0,0.0);// повертаємося на 90 градусів навколо осі X
glColor3f(1.0,0.0,0.0);
auxWireCylinder(0.6,2.0);// циліндр кріплення плеча
// Призма формування плеча
glRotatef(180.0*hspos/100,0.0,1.0,0.0); // рух плеча горизонтальною прокруткою
glTranslatef(1.0,0.5,0.0);// переміщення у кінець кріплення
glColor3f(0.5,0.5,0.5);
auxWireBox(2.0,1.0,1.2);// призма плеча
12.
Матричні перетворення у OpenGL (приклад із роботом)void CMainWin::OnRobot(void) // продовження
{// Кінцевий циліндр формування плеча
glTranslatef(1.0,-0.5,0.0); // переміщення у кінець призми
glColor3f(1.0,0.0,0.0);
auxWireCylinder(0.6,1.0); // кінцевий циліндр формування плеча
// Призма формування ліктя
glRotatef(90.0*hspos/100,0.0,1.0,0.0); // рух ліктя горизонтальною прокруткою
glTranslatef(1.0,0.5,0.0); // переміщення у кінець кріплення
glColor3f(0.0,0.5,0.5);
auxWireBox(2.0,1.0,0.8); // призма плеча
// Кінцевий циліндр формування ліктя
glTranslatef(1.0,-0.5,0.0); // переміщення у кінець ліктя
glColor3f(1.0,0.0,0.0);
auxWireCylinder(0.4,1.0); // кінцевий циліндр формування ліктя
// Схват робота
glColor3f(1.0,0.0,0.0);
glTranslatef(0.5,0.5,0.0); // переміщення у центр кінця плеча
auxWireBox(1.0,0.7,0.4); // призма основи cхвату
glColor3f(0.0,0.0,1.0);
glRotatef(90.0,0.0,0.0,1.0); // повертаємося 90 градусів навколо осі Z
glTranslatef(0.2,-1.5,0.0); // переміщення у край призми схвату
auxWireCylinder(0.1,0.4); // перший циліндр пальця
glTranslatef(-0.4,0.0,0.0); // переміщення у другий край призми схвату
auxWireCylinder(0.1,0.4); // другий циліндр пальця
glPopMatrix(); glPopMatrix(); }
// повертаємося до кінця колони
13.
Матричні перетворення уOpenGL (приклад із
роботом GLU)
void OnOpenGL(void) // example for .NET project with GLU
{ glRotated(360.0 * hspos / 100, 0, 1, 0); glRotated(360.0 * vspos / 100, 1, 0, 0);
glLineWidth(2.0);
// axis of coordinates
glPushMatrix();
glColor3f(1.0, 0.5, 0.0);
gluCylinder(gluNewQuadric(), 3.0, 1.25, 1.0, 20, 20); // base
glColor3f(0.5, 1.0, 0.0);
glRotatef(360.0 * columnPos / 100, 0, 0, 1);
gluCylinder(gluNewQuadric(), 1.25, 1.25, 7.0, 20, 20); // column
glTranslatef(0.0, 0.0, 7.0);
glRotatef(90.0, 1.0, 0.0, 0.0);
glColor3f(0.5, 0.5, 0.0);
glRotatef(360.0 * shoulderPos / 100, 1, 0, 0);
gluCylinder(gluNewQuadric(), 1.0, 1.0, 5.0, 20, 20); // shoulder
glTranslatef(0.0, 0.0, 5.0);
glColor3f(0.0, 0.5, 0.5);
glRotatef(360.0 * elbowPos / 100, 1, 0, 0);
gluCylinder(gluNewQuadric(), 0.7, 0.7, 3.0, 20, 20); // elbow
glTranslatef(0.0, 0.0, 3.0);
glColor3f(0.0, 1.0, 1.0);
glRotatef(360.0 * wristPos / 100, 1, 0, 0);
gluCylinder(gluNewQuadric(), 0.5, 0.5, 1.5, 20, 20); // wrist
glPopMatrix();}
14.
Матричні перетворення у OpenGL (приклад із літаком)Зміни в основній програмі:
1. Обробка повідомлення таймера в карті повідомлень,
2. Запуск таймера у конструкторі вікна: SetTimer (1,25,NULL);
3. Реалізація фунції таймера:
void CMainWin::OnTimer(UINT i)
{k++; Invalidate(FALSE); } // k – лічильник таймера (типу long)
4. Реалізація моделі простору і об’єкта – Функція OnPlane()
void CMainWin::OnPlane(void) // початок
{
double a=1.5,b=3.0;
glPushMatrix();
glScalef(0.5,0.5,0.5);
glPushMatrix();
glTranslatef(0.0,0.0,-210.0);
glRotatef(k,1.0,0.0,0.0); // поворот поверхі
auxWireSphere(200.0); // поверхня землі
glPopMatrix();
glPushMatrix();
glColor3f(0.0,1.0,1.0);
glTranslatef(0.0,7.0,0.0);
auxSolidCylinder(1.5,16.0);
glPopMatrix();
//////////
}
// фюзеляж
15.
Матричні перетворення у OpenGL (приклад із літаком)void CMainWin::OnPlane(void) // закінчення
{ glPushMatrix();
glTranslatef(0.0,7.5,0.0); glColor3f(0.0,1.0,0.0);
for(int i=0;i<100;i++)
{double angle=2*pi*i/10; glRotatef(angle,0.0,1.0,0.0);
glBegin(GL_LINE_STRIP); // ніс літака – половина еліпсоіда
for(double x=0.0;x<a;x=x+0.01)glVertex2f(x,b*sqrt(1.0-(x*x/(a*a))));
glEnd();
}
glPopMatrix();
glPushMatrix();
glTranslatef(0.0,-8.0,0.0); glRotatef(90.0,1.0,0.0,0.0);
auxSolidCone(1.5,2.0);
// хвостова частина фюзеляжу
glPopMatrix();
glColor3f(0.0,0.0,1.0);
glBegin(GL_TRIANGLES);
glVertex3i(0,-10,0); glVertex3i(0,-10,7);glVertex3i(0,-3,0); // хвіст
glVertex3i(0,6,0); glVertex3i(13,-2,0);glVertex3i(0,0,0); // крило
glVertex3i(0,6,0); glVertex3i(-13,-2,0);glVertex3i(0,0,0); // крило
glEnd();
glPushMatrix();
glColor3f(1.0,0.0,0.0);
glTranslatef(7.0,0.0,-0.25);auxSolidCylinder(0.5,3.0); // двигун
glTranslatef(-14.0,0.0,0.0);auxSolidCylinder(0.5,3.0); // двигун
glPopMatrix(); glPopMatrix();
}
informatics