중력가속도를 알고 적분을 이용하여 속도와 거리를 구하는 예
#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();
}