opengl 질문입니다.!
키보드 입력을 받아서 a키나 s키를 누르면 제자리를 회전하고, 회전중에 w키나 z키를 누르면 회전하는 방향으로 이동하는 과제입니다.
Q. 현재진행방향이 (dir_x, dir_z)인데 새로운 진행방향으로 가게 하려면 어떻게 해야하나요?
아래 소스코드 수정좀 부탁드릴게요!
<주어진 조건내용>
*키보드 입력을 이용하여 움직임 제어
-‘a’ : 앞 바퀴를 왼쪽으로 1도 회전 (theta[2]의 값 1증가)
-‘s’ : 앞 바퀴를 오른쪽으로 1도 회전 (theta[2]의 값 1감소)
-‘w’ : 속도 변수 값을 0.1 증가 시킴 (변수 명 : speed)
- ‘z’ : 속도 변수 값을 0.1 감소 시킴
*진행 방향으로 자동차의 위치를 이동시켜야 함
*자동차의 현재 위치를 나타내는 변수 필요
*xz 평면에서 움직이므로 x,z 좌표 필요
변수 예 : loc_x, loc_z
*진행 방향에 따른 위치 이동
loc_x = loc_x + dir_x * speed;
loc_y = loc_y + dir_z * speed;
* 앞 바퀴를 좌/우로 돌린 경우 진행 방향도 변경되어야 함
*진행 방향 계산
-현재 진행 방향 : (dir_x, dir_z)
-앞 바퀴 회전 각도 : theta[2]
- 새로운 진행 방향 : (xp, zp)
xp = dir_x * cos(angle) + dir_z * sin(angle)
zp = -dir_x * sin(angle) + dir_z * cos(angle)
angle = 3.14159 * theta[2] / 180.0 // 라디안 각도
#include <glut.h> #include <stdlib.h> #include <math.h> typedef float point[3]; GLfloat dir_x, dir_z = 0.0; GLfloat speed = 0.0; GLfloat loc_x, loc_z = 0.0; GLfloat xp, zp = 0.0; static GLfloat theta[3] = { 0.0,0.0,0.0 }; /* initial joint angles */ static GLint angle = 2; double size = 1.0; int objectID = 2; void MyTimer(int Value) { theta[0] = theta[0] + theta[2]; theta[1] = theta[1] + speed * 100; xp = dir_x * cos(3.14159 * theta[2] / 180.0) + dir_z * sin(3.14159 * theta[2] / 180.0); zp = -dir_x * sin(3.14159 * theta[2] / 180.0) + dir_z * cos(3.14159 * theta[2] / 180.0); loc_x = loc_x + dir_x * speed; loc_z = loc_z + dir_z * speed; glutPostRedisplay(); glutTimerFunc(50, MyTimer, 1); } void MyKeyboard(unsigned char KeyPressed, int X, int Y) { switch (KeyPressed) { case 'a': theta[2]++; glutPostRedisplay(); break; case 's': theta[2]--; glutPostRedisplay(); break; case 'w': speed += 0.1; glutPostRedisplay(); break; case 'z': speed -= 0.1; glutPostRedisplay(); break; } } void cartorso() { glPushMatrix(); glScaled(5, 1.5, 3); glutSolidCube(1.0); glPopMatrix(); } void whell() { glPushMatrix(); glutSolidTorus(0.4, 0.5, 10, 10); glPopMatrix(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(1, 1, 1, 0, 0, 0, 0, 1, 0); glBegin(GL_LINES); glVertex3f(0, 0, 0); glVertex3f(10, 0, 0); glVertex3f(0, 0, 0); glVertex3f(0, 10, 0); glVertex3f(0, 0, 0); glVertex3f(0, 0, 10); glEnd(); glColor3f(1.0, 0.0, 0.0); if (objectID == 1) { glRotatef(theta[2], xp, 0, zp); glTranslatef(loc_x , 0, loc_z); glRotatef(theta[0], 0.0, 1.0, 0.0); cartorso(); glPushMatrix(); glTranslatef(1.5, 0, 2); // 앞 - 오른쪽 바퀴 glRotatef(theta[2], 0.0, 1.0, 0.0); //좌우 회전 glRotatef(theta[1], 0.0, 0.0, 1.0); //전진, 후진 whell(); glPopMatrix(); glPushMatrix(); glTranslatef(1.5, 0, -2); //앞 - 왼쪽 바퀴 glRotatef(theta[2], 0.0, 1.0, 0.0); //좌우회전 glRotatef(theta[1], 0.0, 0.0, 1.0); //전진, 후진 whell(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, 0, 2); //뒤 - 오른쪽바퀴 glRotatef(theta[1], 0.0, 0.0, 1.0); //전진, 후진 whell(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, 0, -2); //뒤 - 왼쪽바퀴 glRotatef(theta[1], 0.0, 0.0, 1.0); whell(); glPopMatrix(); } glFlush(); glutSwapBuffers(); } void menu2(int id) { if (id <12) objectID = id; theta[0] = theta[1] = theta[2] = 0.0; dir_x =1.0; dir_z =0.0; loc_x = 0.0; loc_z = 0.0; speed = 0.0; glutTimerFunc(50, MyTimer, 1); glutPostRedisplay(); } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-10.0, 10.0, -10.0 * (GLfloat)h / (GLfloat)w, 10.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0); else glOrtho(-10.0 * (GLfloat)w / (GLfloat)h, 10.0 * (GLfloat)w / (GLfloat)h, 0.0, 10.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void myinit() { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess = { 100.0 }; GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 0.0, 0.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 10.0, 10.0, 10.0, 0.0 }; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glClearColor(1.0, 1.0, 1.0, 1.0); glColor3f(1.0, 0.0, 0.0); } /* allocate quadrics with filled drawing style */ void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 800); glutCreateWindow("Car"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutKeyboardFunc(MyKeyboard); glutCreateMenu(menu2); glutAddMenuEntry("자동차", 1); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); }
댓글 달기