编辑:原来我只是换了一些值。
我正在使用OpenGL,并在Windows计算机上用C编写代码,我正在尝试进行一个非常基本的碰撞检测。
现在,我试着看看一个点牛,奥兹是否在两个盒子里:
int collision(int box[2][4]) {
int col;
int i;
for (i=0;i<2;i++){
col = 0;
printf("x1:%.0f y1:%.0f x2:%.0f y2:%.0f \n",colbox[i][0],colbox[i][1],colbox[i][2],colbox[i][3]);
printf("Ox:%.1f Oy:%.1f Oz:%.1f \n" , Ox,here,Oz);
if ((colbox[i][0] < Ox) && (Ox < colbox[i][2])&& (colbox[i][1] < Oz) && (colbox[i][3] > Oz))
return 1;
else
return 0;
}
}
我也尝试过一些变化,比如没有任何东西传递到函数,将循环放在函数之外等等。问题似乎是等式检查?
在我试图做的最底层,是查看一个点(相机)是否在一个边界内(这是一个二维数组中保存的4个点的集合),如果它在列出的任何边界内,则返回1如果该点不在任何边界中,则返回0。
当这确实起作用时,它只对一个区域起作用,即如果我移到第一个列出的有界区域,它会正确返回,但第二个区域不会正确返回。
完整的代码,如果它真的有用:
// Values
double Ox=0, Oz=0;
float Oy=1.0;
double asp=1; // Aspect ratio
double dim=20; // Size of world
double fov=55; // Field of View
double ph,th = 0;
// angle of rotation for the camera direction
float angle = 0.0;
// actual vector representing the camera's direction
float lx=0.0,lz=-1.0;
// the key states. These variables will be zero
//when no key is being presses
float deltaAngle = 0.0;
float deltaMove = 0;
double here;
int collide;
// {x1,y1,x2,y2}
double colbox[2][4] = {
{3,3,6,6},
{-1,-14,-3,-16}
};
//front-1 back-2 left-3 right-4
int collision(double box[2][4]) {
int i;
for (i=0;i<2;i++){
col = 0;
printf("x1:%.0f y1:%.0f x2:%.0f y2:%.0f \n",colbox[i][0],colbox[i][1],colbox[i][2],colbox[i][3]);
printf("Ox:%.1f Oy:%.1f Oz:%.1f \n" , Ox,here,Oz);
if ((colbox[i][0] < Ox) && (Ox < colbox[i][2])&& (colbox[i][1] < Oz) && (colbox[i][3] > Oz))
return 1;
else
return 0;
}
}
//test
static void ball(double x,double y,double z,double r)
{
// Save transformation
glPushMatrix();
// Offset, scale and rotate
glTranslated(x,y,z);
glScaled(r,r,r);
// White ball
glColor3f(1,1,1);
glutSolidSphere(1.0,16,16);
// Undo transofrmations
glPopMatrix();
}
static void square(double r) {
glPushMatrix();
glScaled(r,r,r);
glColor3f(1,0,0);
glBegin(GL_QUADS);
glVertex3f(-1,0,-1);
glVertex3f(1,0,-1);
glVertex3f(1,0,1);
glVertex3f(-1,0,1);
glEnd();
glPopMatrix();
}
//test
void computePos(float deltaMove) {
Ox += deltaMove * lx * 0.1f;
Oz += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle) {
angle += deltaAngle;
lx = sin(angle);
lz = -cos(angle);
}
// display
void display() {
here = 2.0f*Oy;
if (deltaMove)
computePos(deltaMove);
if (deltaAngle)
computeDir(deltaAngle);
const double len=2.0;
// Erase the window and the depth buffer
glClearColor(0.3,0.5,1.0,1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Enable Z-buffering in OpenGL
glEnable(GL_DEPTH_TEST);
// Set perspective
glLoadIdentity();
gluLookAt(Ox,2,Oz, Ox+lx, here, Oz+lz, 0,1,0);
ball(5,5,5,2); ball(-2,0,-15,1);
square(15);
glColor3f(1,1,1);
glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(len,0.0,0.0);
glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,len,0.0);
glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,0.0,len);
glEnd();
// Label axes
glRasterPos3d(len,0.0,0.0);
Print("X");
glRasterPos3d(0.0,len,0.0);
Print("Y");
glRasterPos3d(0.0,0.0,len);
Print("Z");
// Render the scene and make it visible
glColor3f(0,0,0);
glWindowPos2i(5,5);
Print("Ox:%.1f Oy:%.1f Oz:%.1f lx:%.1f lz:%.1f Collide:%d", Ox,here,Oz,lx,lz,collide);
ErrCheck("display");
glFlush();
glutSwapBuffers();
}
void key(unsigned char ch,int x,int y) {
// Exit on ESC
if (ch == 27)
exit(0);
// WASD controls
else if (ch == 'a' || ch == 'A')
deltaAngle = -0.05;
else if (ch == 'd' || ch == 'D')
deltaAngle = 0.05;
else if (ch == 'w' || ch == 'W') {
collide=collision(colbox);
deltaMove = 1; }
else if (ch == 's' || ch == 'S') {
collide=collision(colbox);
deltaMove = -1; }
else if ((ch == 'e' || ch == 'E') && here < 4)
Oy += 0.01;
else if ((ch == 'c' || ch == 'C') && here > .5)
Oy -= 0.01;
Project(fov,asp,dim);
glutPostRedisplay();
}
void reshape(int width,int height) {
// Ratio of the width to the height of the window
asp = (height>0) ? (double)width/height : 1;
// Set the viewport to the entire window
glViewport(0,0, width,height);
// Set projection
Project(fov,asp,dim);
}
void releaseKey(unsigned char ch, int x, int y) {
if (ch == 'a' || ch == 'A')
deltaAngle = 0;
else if (ch == 'd' || ch == 'D')
deltaAngle = 0;
else if (ch == 'w' || ch == 'W')
deltaMove = 0;
else if (ch == 's' || ch == 'S')
deltaMove = 0;
Project(fov,asp,dim);
glutPostRedisplay();
}
int main(int argc,char* argv[]) {
// Initialize GLUT
glutInit(&argc,argv);
// Request double buffered, true color window with Z buffering at 600x600
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,500);
glutCreateWindow("Haunted House");
// Set callbacks
glutDisplayFunc(display);
glutReshapeFunc(reshape);
// glutSpecialFunc(special);
glutKeyboardFunc(key);
glutKeyboardUpFunc(releaseKey);
// Pass control to GLUT so it can interact with the user
ErrCheck("init");
glutMainLoop();
return 0;
}
最佳答案
我想当你有I=1第二行
if ((colbox[i+1][0] < Ox) && (Ox < colbox[i+1][2])&& (colbox[i+1][1] < Oz) && (colbox[i+1][3] > Oz))
从2号阵列中走出来(因为最大索引是1。)
所以,考虑到它读取的内存不在数组中(我认为通常是可以的),你会发现这种情况可能失败很多,甚至大部分时间,因为它处理的是基本随机数据然后返回0。
关于c - 简单的碰撞检测?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11251881/