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();
}

댓글 달기