'Math for Game/중력가속도와 적분'에 해당되는 글 1건

  1. 2018.09.16 중력가속도와 적분 응용 예

중력가속도를 알고 적분을 이용하여 속도와 거리를 구하는 예


#include <iostream>


using namespace std;


int main()

{

cout << "적분을 이용한 중력가속도와 거리 테스트" << endl;


// 가속도의 시간에 대한 적분 결과는 속도(시간당 거리)이다

// 속도의 시간에 대한 적분 결과는 거리(위치, 좌표)이다


//가속도는 G = 9.8 * t^0 으로 볼 수 있으므로 시간 t에 대한 적분이 가능하다


float G = -9.8F;    // 중력가속도(아래로 작용하므로 음수,  스크린인 경우에는 양수이어야 함)

float t = 0.0F;      // 시작 시점부터 현재까지 누적된 시간(초)

float C1 = 0.0F;    // 초기속도를 나타내는 상수

float C2 = 0.0F;    // 초기위치를 나타내는 상수


// G를 시간 t에 대하여 적분하여 속도를 구하면 다음과 같다 ( G * t^0 를 적분한다)

float Vy = G * t + C1;     // 적분상수 C1는 t=0일 때의 초기속도


// 속도(Vy)를 시간 t에 대하여 적분하여 거리를 구하면 다음과 같다

float y = 0.5 * G * ( t * t ) + ( C1 * t ) + C2;    // 적분상수 C2는 초기 위치(초기 y값)


// 위의 식에서 0.5 대신에 1/2을 사용하면 안된다. 정수끼리 나눗셈하면 정수가 나오기 때문

cout << "초기의 위치 y=" << y << endl;


// 단위시간(1프레임)당 100미터의 속도로 바닥(0,0)에서 위를 향해 발사된 포탄이 

// 바닥에 도달하기 까지 위치(좌표)를 화면에 표시해보고 정점의 위치를 확인한다


C1 = 100;  //초기속도 

C2 = 0;  //초기위치


do {

y = 0.5 * G * ( t * t ) + ( C1 * t ) + C2;     // 0.5 대신에 1/2을 사용하면 안됨

cout << "y = " << y << endl;

t++;

} while (y >= 0);


return 0;

}




아래의 예는 화면 아래에서 위를 향하여 볼을 발사하면 점차 상승속도가 줄어들면서 결국 바닥으로 떨어지면서 가속된다


MainWindow.h


#ifndef MAINWINDOW_H

#define MAINWINDOW_H


#include <QMainWindow>

#include <QPaintEvent>

#include <QTimerEvent>


class MainWindow : public QMainWindow

{

    Q_OBJECT


public:

    MainWindow(QWidget *parent = 0);

    ~MainWindow();


    float G, t;

    int64_t startMS;

    float initSpd, initPos, spdX, spdY, x, y;


    void paintEvent(QPaintEvent *e);

    void timerEvent(QTimerEvent *e);


    void gameLoop();

};


#endif // MAINWINDOW_H




MainWindow.cpp


#include "mainwindow.h"

#include <QPainter>

#include <QDateTime>


MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

{

    G = 300.0F;//9.8F;

    t = 0;

    initSpd = -500;

    initPos = 500;

    spdX = 0;

    spdY = initSpd;

    x = 300;

    y = initPos;

    startTimer(40);

    startMS = QDateTime::currentMSecsSinceEpoch();

}


MainWindow::~MainWindow()

{

}


void MainWindow::paintEvent(QPaintEvent *e)

{

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);


    painter.drawEllipse(x,y,100,100);

}

void MainWindow::gameLoop()

{

    int64_t duration = QDateTime::currentMSecsSinceEpoch()-startMS;

    t = duration/1000.0F;

    y = 0.5F * G * (t * t) + ( initSpd * t ) + initPos;

    repaint();

}

void MainWindow::timerEvent(QTimerEvent *e)

{

    gameLoop();

}



main.cpp


#include "mainwindow.h"

#include <QApplication>


int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    MainWindow w;

    w.resize(650,600);

    w.setWindowTitle("Acceleration Movement");


    w.show();


    return a.exec();

}

Posted by cwisky