我正在尝试将球从墙壁弹起并且彼此弹开的应用程序。从墙壁弹起的效果不错,但是我很难让它们弹起。这是我用来使它们弹回另一个球的代码(用于测试,我只有2个球)

 // Calculate the distance using Pyth. Thrm.
        GLfloat x1, y1, x2, y2, xd, yd, distance;
        x1 = balls[0].xPos;
        y1 = balls[0].yPos;
        x2 = balls[1].xPos;
        y2 = balls[1].yPos;

        xd = x2 - x1;
        yd = y2 - y1;

        distance = sqrt((xd * xd) + (yd * yd));

        if(distance < (balls[0].ballRadius + balls[1].ballRadius))
        {
            std::cout << "Collision\n";
            balls[0].xSpeed = -balls[0].xSpeed;
            balls[0].ySpeed = -balls[0].ySpeed;

            balls[1].xSpeed = -balls[1].xSpeed;
            balls[1].ySpeed = -balls[1].ySpeed;

        }


发生的情况是它们随机反弹或彼此通过。我缺少一些物理学吗?

编辑:这是全部功能

// Callback handler for window re-paint event
void display()
{
    glClear(GL_COLOR_BUFFER_BIT);    // Clear the color buffer
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);


    // FOR LOOP
    for (int i = 0; i < numOfBalls; i++)
    {
        glLoadIdentity();                // Reset model-view matrix
        int numSegments = 100;
        GLfloat angle = 0;
        glTranslatef(balls[i].xPos, balls[i].yPos, 0.0f);  // Translate to (xPos, yPos)

        // Use triangular segments to form a circle
        glBegin(GL_TRIANGLE_FAN);
        glColor4f(balls[i].colorR, balls[i].colorG, balls[i].colorB, balls[i].colorA);
        glVertex2f(0.0f, 0.0f);       // Center of circle

        for (int j = 0; j <= numSegments; j++)
        {
            // Last vertex same as first vertex
            angle = j * 2.0f * PI / numSegments;  // 360 deg for all segments
            glVertex2f(cos(angle) * balls[i].ballRadius, sin(angle) * balls[i].ballRadius);
        }
        glEnd();

        // Animation Control - compute the location for the next refresh
        balls[i].xPos += balls[i].xSpeed;
        balls[i].yPos += balls[i].ySpeed;

        // Calculate the distance using Pyth. Thrm.
        GLfloat x1, y1, x2, y2, xd, yd, distance;
        x1 = balls[0].xPos;
        y1 = balls[0].yPos;
        x2 = balls[1].xPos;
        y2 = balls[1].yPos;

        xd = x2 - x1;
        yd = y2 - y1;

        distance = sqrt((xd * xd) + (yd * yd));

        if(distance < (balls[0].ballRadius + balls[1].ballRadius))
        {
            std::cout << "Collision\n";
            balls[0].xSpeed = -balls[0].xSpeed;
            balls[0].ySpeed = -balls[0].ySpeed;

            balls[1].xSpeed = -balls[1].xSpeed;
            balls[1].ySpeed = -balls[1].ySpeed;

        }
        else
        {
            std::cout << "No collision\n";
        }

        // Check if the ball exceeds the edges
        if (balls[i].xPos > balls[i].xPosMax)
        {
            balls[i].xPos = balls[i].xPosMax;
            balls[i].xSpeed = -balls[i].xSpeed;
        }
        else if (balls[i].xPos < balls[i].xPosMin)
        {
            balls[i].xPos = balls[i].xPosMin;
            balls[i].xSpeed = -balls[i].xSpeed;
        }

        if (balls[i].yPos > balls[i].yPosMax) {
            balls[i].yPos = balls[i].yPosMax;
            balls[i].ySpeed = -balls[i].ySpeed;
        }
        else if (balls[i].yPos < balls[i].yPosMin)
        {
            balls[i].yPos = balls[i].yPosMin;
            balls[i].ySpeed = -balls[i].ySpeed;
        }
    }
    glutSwapBuffers();  // Swap front and back buffers (of double buffered mode)
}


**注意:大多数函数使用带有numOfBalls的for循环作为计数器,但是为了测试碰撞,我仅使用2个球,因此balls[0]balls[1]

最佳答案

这里有一些要考虑的事情。

如果(xSpeed,ySpeed)的长度与.ballRadius大致相当,则两个球有可能在模拟时钟的“滴答声”之间“穿越”(一步)。考虑两个完全垂直移动的球,一个向上,一个向下,水平间隔1 .ballRadius。在现实生活中,它们显然会发生冲突,但是如果.ySpeed.ballRadius,则模拟很容易错过此事件。

其次,您改变球的向量会导致每个球静止,因为

balls[0].xSpeed -= balls[0].xSpeed;


是一种非常奇特的写作方式

balls[0].xSpeed = 0;

关于c++ - 使球彼此弹起(openGL),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19443133/

10-12 05:07