2013-12-15 35 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)); 

} 

CPP的

#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 

主要

#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

有一个SMaL公司l你在第一个代码块中做的物理问题。如果你想模拟引力,你会想用牛顿的引力定律来计算你的加速度。你目前拥有的是胡克定律;具有线性阻力的弹簧力。要立即回答关于如何将景点中心从点(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)的期望的吸引力的中心位置。这将允许你移动你的力源,但是这仍然没有解决你的力是弹性的问题,而不是引力(反平方定律)。要做到这一点,你会想要的东西,看起来像下面

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); 

注意,以便采取的方向考虑,我已经dx/distdy/dist乘以F = G*m1*m2/dist^2。这相当于cos(angle)sin(angle),其中angle是最好未计算的数量(将指定力的方向)。 mass将是吸引你的粒子(?)的物体的质量,并且由于我们只是计算加速度,所以粒子质量不再。如果您想要将线性拖回到加速中,您也可以轻松做到这一点,这将使轨道更加稳定。

请注意,通过使用矢量可以大大清除此代码。如果需要澄清,请告诉我。

+0

我使用了这段代码,但它在球体上没有任何变化,它只是通过重力不变而改变了它的运动轨迹。 – Student123

+0

你对G,质量等有什么价值?此外,请检查以确保dx和dy以及加速度的计算结果不为零。这可能是因为你忘了设定一个值,或者你让G或质量太小。 – Nathan