2017-01-18 18 views
3

У меня возникают проблемы с реализацией силы тяжести на объектах.Применение силы тяжести к объектам

У меня есть куча круглых объектов, которые я рисую с использованием OpenGL. Я использую delta-x и delta-y для перемещения кругов (шаров). Я пытаюсь добавить гравитационную константу в координаты каждого кадра, чтобы имитировать то, что вы тянули вниз, но я точно не знаю, как это сделать.

Вот соответствующий код:

class Ball 
{ 
    public: 
     double x; 
     double y; 
     double radius; 
     double deltaX; 
     double deltaY; 
}; 


std::vector<Ball> gAllBalls; // a vector of balls with random positions and delta-values 
double gGravity = ?; // gravitational constant - I know it's 92 m/s^s, but I don't know how to apply that to deltaX and deltaY 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    for (auto &thisBall : gAllBalls) 
    { 
     // draw 
     glColor3d(thisBall.red, thisBall.green, thisBall.blue); 
     DrawCircle(thisBall.x, thisBall.y, thisBall.radius); 

     // gravity - not working 
     if (thisBall.y + thisBall.radius < gScreenHeight - gGravity) 
     { 
      thisBall.y += gGravity; 
     } 

     // wall bouncing 
     if (thisBall.y + thisBall.radius + thisBall.deltaY >= gScreenHeight) // up 
     { 
      thisBall.deltaY = -thisBall.deltaY; 
     } 

     if (thisBall.y + thisBall.deltaY - thisBall.radius < 0) // down 
     { 
      thisBall.deltaY = -thisBall.deltaY; 
     } 

     if (thisBall.x + thisBall.deltaX - thisBall.radius < 0) // left 
     { 
      thisBall.deltaX = -thisBall.deltaX; 
     } 

     if (thisBall.x + thisBall.radius + thisBall.deltaX >= gScreenWidth) // right 
     { 
      thisBall.deltaX = -thisBall.deltaX; 
     } 

     // move 
     thisBall.x += thisBall.deltaX; 
     thisBall.y += thisBall.deltaY; 
    } 
    glutSwapBuffers(); 
    glutPostRedisplay(); 
} 

Большая проблема у меня в том, что я не знаю, как рассчитать силу тяжести, так как я использую deltaX и deltaY вместо того, чтобы отдельные скорости и для расчета 92 м/с^2. Однако, независимо от того, на что я настроил гравитацию, шары не ведут себя так, как должны - независимо от силы тяжести, поэтому должно быть что-то еще неправильно, но я не знаю, что.

+0

'thisBall.y + = gGravity;' Это приведет к постоянной скорости, а не постоянному ускорению. Если вы настроите deltaY, а не Y, вы, вероятно, приблизитесь к тому, что собираетесь. Лучше всего было бы работать в технических единицах, таких как метры и секунды, а не пикселях и произвольных временных шагах, а затем конвертировать между ними по мере необходимости. Наконец, ваше значение для «G» выключено, это действительно 9,8 м/сек^2 –

+0

А, конечно, это имеет больше смысла. Я изменил его на deltaY вместо Y, и он изначально кажется сработавшим, но шары начинают ускоряться все быстрее и быстрее вместо замедления. Я просто использую 1 как константу силы тяжести. Я бы хотел использовать лучшие юниты, но я не уверен, как их реализовать. У вас есть предложения или ресурсы? – Grav

+0

«** 92 ** m/s^2», где вы имитируете, какой-то ультра-Юпитер или маленькую звезду? – genpfault

ответ

4

Я думаю, что проблема здесь в физике, а не в технике программирования. В вашем случае я бы изменил «дельта» членов вашего класса Ball на «скорость», так как они являются единицей расстояния, которая меняет положение вашего объекта за цикл (время), однако это всего лишь предложение сделать это легче визуализировать ...

class Ball 
{ 
    public: 
     double x; 
     double y; 
     double radius; 
     double speedX; 
     double speedY; 
}; 

на втором месте, я в вашем коде, вы изменяете «у» члена, а не скорости, а так как гравитация изменяет скорость, отсюда и проблемы. Попробуйте сделать это, и для целей отладки я бы попытался с пунктуальными объектами (без радиуса, просто с координатами (x, y)).

Итак, в заключение, я бы просто изменить код тяжести на следующее:

// gravity - 'fixed' 
    if (thisBall.y + thisBall.radius < gScreenHeight - gGravity) 
    { 
     thisBall.speedY -= gGravity; //notice the '-' 
    } 

Значение силы тяжести должно быть абсолютным и положительным, так, чтобы держать вещи так просто, как Возможное. Если вы попробуете это, у вас должен быть идеальный простой физический симулятор с шаром постоянной скорости X (только с изменением направления, а не с амплитудой). Пожалуйста, попробуйте это, и дайте мне знать, как это получилось, удачи, держите его вверх =)

+0

Как физик, что 'speedY - = gGravity;' выглядит странно для меня. Это сделало бы 'gGravity' само отрицательным числом и положительно суммирует его (' + = '). – datenwolf

+0

Спасибо! Это приблизило меня к желаемому результату. Тем не менее, у меня все еще есть небольшая проблема: когда шары отскакивают, они отскакивают все выше и выше, каждый прыжок вместо замедления и, в конце концов, оседает на дно. Единственное, что я изменил, это гравитация, влияющая на скорость, а не на положение. У вас есть какие-либо соображения, почему это происходит? – Grav