2013-12-15 5 views
0

내가 만든 작은 2D 게임에서 물리학을 위해 RK4를 사용했지만 중력에 관해서는 모든 개체를 0,0으로 끌어 올렸는데 어떻게 변경할 수 있습니까? 시간은 아직 너무에 작은이 있습니다RK4 중력 끌어 오기 방향

#include "Gravity.h" 

gravity::accelerationReturn gravity::acceleration(state & state , float time) //Returns a struct instead easier to put into a vector. 
{ 
    accelerationReturn return1; 
    const float k =9.8; 
    const float b = 1; 
    return1.Xaccel = -k * state.pos.getX() - b* state.vel.getX(); 
    return1.Yaccel = -k * state.pos.getY() - b* state.vel.getY(); 
    return return1; 
} 


gravity::derivative gravity::evaluate(state & initial, float time, float deltaTime,derivative & Derivative) 
{ 
    state state; 
    state.pos.setXY(initial.pos.getX() + Derivative.dpos.getX()*deltaTime, 
     initial.pos.getY() - Derivative.dpos.getY()*deltaTime); 

    state.vel.setXY(initial.vel.getX() + Derivative.dvel.getX() * deltaTime, 
     initial.vel.getY() + Derivative.dvel.getY() * deltaTime); 

     derivative output; 
     output.dpos.setXY(state.vel.getX(),state.vel.getY()); 
     output.dvel.setXY(acceleration(state,time + deltaTime).Xaccel, 
      acceleration(state,time + deltaTime).Yaccel); 
     return output; 

} 

void gravity::integrate(state & State , float time, float deltaTime) 
{ 

    derivative a = evaluate(State ,time,0.0f,derivative()); 
    derivative b = evaluate(State,time,deltaTime * 0.5f,a); 
    derivative c = evaluate(State,time,deltaTime * 0.5f,b); 
    derivative d = evaluate(State,time,deltaTime,c); 

    Vector dpdt; 
    Vector dvdt; 
    dpdt.setXY((1.0f/10.0f * (a.dpos.getX() + 2.0f * (b.dpos.getX() + c.dpos.getX()) + d.dpos.getX())), 
       (1.0f/10.0f * (a.dpos.getY() + 2.0f * (b.dpos.getY() + c.dpos.getY()) + d.dpos.getY()))); 
    dvdt.setXY((1.0f/10.0f * (a.dvel.getX() + 2.0f * (b.dvel.getX() + c.dvel.getX()) + d.dvel.getX())), 
       (1.0f/10.0f * (a.dvel.getY() + 2.0f * (b.dvel.getY() + c.dvel.getY()) + d.dvel.getY()))); 


    State.pos.setXY ((State.pos.getX() + dpdt.getX() * deltaTime),(State.pos.getY() + dpdt.getY() * deltaTime)); 
    State.vel.setXY ((State.vel.getX() + dvdt.getX() * deltaTime),(State.vel.getY() + dvdt.getY() * deltaTime)); 

} 

)

#include "Gravity.h" 
#include <iostream> 
#include "SFML\Graphics.hpp" 
#include "SFML\System.hpp" 

using namespace std; 

int main() 
{ 


    gravity grav; 
    gravity::state marrio; 
    marrio.pos.setXY(500,500); 


    sf::RenderWindow mwindow(sf::VideoMode(800, 800), "my window"); 
    sf::CircleShape shape(50); 
    shape.setFillColor(sf::Color(100,250,250)); 

    sf::Time timeC; 
    float time; 
    float dTime = 0.01f; 

    sf::Clock timePhysics; 
    while(mwindow.isOpen()) 
    { 

       timeC = timePhysics.getElapsedTime(); 
       time = timeC.asSeconds(); 
       grav.integrate(marrio,time,dTime); 
       time += dTime; 
       cout<< "pos  vel"<<endl<<marrio.pos.getX()<<" "<<marrio.pos.getY()<<" "<< 
       marrio.vel.getX()<<" "<<marrio.vel.getY()<<endl; 
       shape.setPosition(marrio.pos.getX(),marrio.pos.getY()); 



       mwindow.clear(); 
       mwindow.draw(shape); 
       mwindow.display(); 
    } 

    system("PAUSE"); 
    return 0; 
} 
+0

충분한 정보가 여기에 있다고 생각하지 않습니다. 관련 코드를 게시 할 수 있습니까? – shuttle87

답변

0

#ifndef GRAVITY_H 
#define GRAVITY_H 

#include "2DVector.h" 


class gravity :Vector 
{ 
private: 



    float time; //current time 
    float deltaTime; // previous time 
public: 
    struct accelerationReturn //for returning acceleration 
    { 
     float Xaccel; 
     float Yaccel; 
    }; 
    struct state //current state of object. 
    { 
     Vector pos; //position 
     Vector vel; //velocity 
    }; 
    struct derivative 
    { 
     Vector dpos; // derivative of posistion is velocity. 
     Vector dvel; // derivative of velocity is acceleration. 
    }; 

    accelerationReturn acceleration (state &,float); //calculates the new acceleration 
    derivative evaluate (state & , float , float , derivative &); //gets derived values 
    void integrate (state &, float , float); 




}; 
#endif 

주요 cpp가 그것을 언급 첫 번째 코드 블록에서 수행중인 물리 문제. 중력 가속도를 모델링하려고한다면, 뉴턴의 중력 법칙을 사용하여 가속도를 계산하는 것이 좋습니다. 당신이 현재 가지고있는 것은 훅의 법칙입니다. 선형 항력을 가진 스프링 력. 끌기 중심을 점 (0,0)에서 멀리 떨어 뜨리는 방법에 대한 질문에 즉시 대답하려면 오프셋을 포함해야하는 것을 간단히 변경할 수 있습니다. 즉,

return1.Xaccel = -k * (state.pos.getX() - xOffset) - b* state.vel.getX(); 
return1.Yaccel = -k * (state.pos.getY() - yOffset) - b* state.vel.getY(); 

어디 xOffsetyOffset 어트랙션의 원하는 중심의 위치 (x, y)를 정의한다. 이것은 당신이 당신의 힘 소스를 움직일 수있게 해줄 것입니다, 그러나 이것은 당신의 힘이 중력이 아닌 탄력적 인 문제를 해결하지 못했습니다 (역 방정식). 이렇게하려면, 당신은 계정에 방향을 위해, 내가 dx/distdy/dist하여 F = G*m1*m2/dist^2을 곱 한 것을 다음

float dx = state.pos.getX() - xOffset; // again xOffset is the source location 
float dy = state.pos.getY() - yOffset; 
float distSqrd = dx*dx + dy*dy; 
float dist = sqrt(distSqrd); 
return1.Xaccel = -G * mass * dx/(distSqrd * dist); 
return1.Yaccel = -G * mass * dy/(distSqrd * dist); 

공지 사항과 같은 일을 할 것입니다. 이것은 cos(angle)sin(angle)과 동일합니다. 여기서 angle은 계산되지 않은 상태로 남겨 두는 것이 가장 좋습니다 (힘의 방향을 지정). mass은 입자를 끌어 당기는 대상의 질량 (?)이며, 입자의 질량은 가속을 계산하기 때문에 중단됩니다. 선형 드래그를 가속에 다시 추가하려면 쉽게 그렇게 할 수 있습니다. 이렇게하면 궤도를 훨씬 안정적으로 만들 수 있습니다.

이 코드는 벡터를 사용하여 상당히 정리할 수 있습니다. 설명이 필요한지 알려주세요.

+0

이 코드를 사용했지만 중력에 의해 변경되지 않은 프로젝트에서 계속해서 변경된 공을 전혀 변경하지 않은 것처럼 보입니다. – Student123

+0

G, 질량 등에 어떤 값을 사용 했습니까? 또한 dx와 dy 및 가속도에 대한 계산 결과가 0이 아닌지 확인하십시오. 값을 설정하는 것을 잊었거나 G 또는 질량을 너무 작게 설정했을 수 있습니다. – Nathan