2011-06-17 53 views
0

问题由原始的海报撤销问题打圈计算

嘿所以运行下面的代码我方应该周游了一圈的时候,但有某种问题与计算功能x,y应该根据行进的速度和角度发生移动。

它成功地四处走动,但没有正确的方式。第二和第四象限是倒转的,向内弯曲而不是向外弯曲。

我无法弄清楚问题是什么......任何人都想帮忙?

#include<SFML/Graphics.hpp> 
#include<SFML/System.hpp> 
#include<cmath> 
#include<vector> 
# define M_PI 3.14159265358979323846 

sf::RenderWindow Window; 

template<typename T> 
void CalculateMove(T Time, T Speed, T Angle, T& buffX, T& buffY) 
{ //Make the degrees positive 
    if(Angle<0) Angle= 360-Angle; 
    //determine what quadrant of circle we're in 
    unsigned int Quadrant= 1; 
    if(Angle>90) Quadrant= 2; 
    if(Angle>180) Quadrant= 3; 
    if(Angle>270) Quadrant= 4; 

    //anything above 90 would be impossible triangle 
    Angle= (float)(Angle-(int)Angle)+(float)((int)Angle%90); 

    // calculates x and y based on angle and Hypotenuse.02433 
    if((int)Angle!=0){ 
     buffX= sin(Angle/180 * M_PI)/ (1.f/(Speed*Time)); 
     buffY= sin((180-Angle-90)/ 180 * M_PI)/ (1.f/(Speed*Time));} 

    else{// Movement is a straight line on X or Y axis 
     if(Quadrant==0 || Quadrant==2) buffX= Speed*Time; 
     if(Quadrant==1 || Quadrant==4) buffY= Speed*Time;} 

    //Quadrant Factor (positive or negative movement on the axis) 
    switch(Quadrant){ 
    case 1: break; 
    case 2: buffX=-buffX; break; 
    case 3: buffX=-buffX; buffY=-buffY; break; 
    case 4: buffY=-buffY; break;} 
}; 

///////////////////////////////////////// Mysprite //////////////////////////////// 
class mySprite : public sf::Sprite 
{ 
private: 
    float velocity; 
    float angle; 

public: 
    // all the values needed by the base class sprite(); 
    mySprite(
     const sf::Image& Img, 
     const sf::Vector2f& Position = sf::Vector2f(0, 0), 
     const sf::Vector2f& Scale = sf::Vector2f(1, 1), 
     float Rotation = 0.f, 
     const float Angle= 0.f, 
     const float Velocity= 0.f, 
     const sf::Color& Col = sf::Color(255, 255, 255, 255)): 
     Sprite(Img, Position, Scale, Rotation, Col){ 
     angle= Angle; 
     velocity= Velocity;}; 

    float Velocity(){return velocity;}; 
    void SetVelocity(float newVelocity){velocity=newVelocity;}; 
    float Angle(){return angle;}; 
    void SetAngle(float newAngle){angle=(float)(newAngle-(int)newAngle)+(float)((int)newAngle%360);}; 

    void Update(){ 
     float frameTime= Window.GetFrameTime(); 
     float X=0,Y=0; 
     CalculateMove(frameTime,velocity,angle,X,Y); 
     Move(X,-Y); 
    }; 

    void Accelerate(float PPS){velocity+=PPS;}; 
    void Turn(float degrees){ 
     float test= (float)((angle+degrees)- (int)(angle+degrees)); //TODO: Get rid of these test 
     float test2=(float)((int)(angle+degrees)%360); 
     float test3=test+test2; 
     angle=(float)((angle+degrees)-(int)(angle+degrees))+(float)((int)(angle+degrees)%360);}; 

    void Reflect(float CollAngle){ 
     SetRotation(-GetRotation()); 
     angle=-angle; 
     //TODO: factor in the collision angle 
    }; 
}; 

int main() 
{ 
    Window.Create(sf::VideoMode(800, 600), "Pong! by Griffin Howlett"); 
    sf::Image img; 
    img.Create(30,50,sf::Color(255,0,0)); 
    mySprite box(img, sf::Vector2f(400,200), sf::Vector2f(1,1), 0, 180, 200); 
    Window.Display(); 

    for(;;){ 
     Window.Clear(); 
     box.Update(); 
     box.Turn(45.0*Window.GetFrameTime()); 
     Window.Draw(box); 
     Window.Display(); 
    } 

} 

回答

0

看来我错在假设的三角形形成,并且用于计算以获得于x所需的运动,y坐标总是自动使用Y轴作为侧相反的“角度”的,并坐标是第2和第4象限的倒退,感谢其他反馈!

下面是更新的代码:

if((int)Angle!=0){ 
     if(Quadrant==2 || Quadrant==4) Angle=90-Angle; //The unit circle triangle is flipped otherwise, causing x and y to be switched 
     buffY= sin(Angle/180 * M_PI)/ (1.f/(Speed*Time)); 
     buffX= sin((180-Angle-90)/ 180 * M_PI)/ (1.f/(Speed*Time));} 

通过执行90角即时切换用于寻找X,虚三角形的Y侧角....

4

你的第一个错误:

if(Angle<0) Angle= 360-Angle; 

应该是:

if(Angle<0) Angle= 360+Angle; 

我不明白为什么你要分割的角度成象限的麻烦。你认为sin函数只定义了0到90度的范围吗?

+0

所以我可以后来使x和y运动基于象限为负或正位于 – Griffin 2011-06-17 03:19:03

+1

@Griffin,sin(和cos)函数将自动提供适当角度的负数。 – 2011-06-17 03:20:42

0

不知道所有的问题,但是这行代码是错误的:

if(Angle<0) Angle= 360-Angle; 

如果Angle < 0然后360 - 角将> 360

你也可以清理象限设置代码,否则当角度> 270时,您将分配4次。

int Quadrant = 1; 
if (Angle > 270) 
{ 
    Qadrant = 4; 
} 
else if (Angle > 180) 
{ 
    Quadrant = 3; 
} 
else if (Angle > 90) 
{ 
    Quadrant = 2; 
} 
+0

会清理象限设置代码保存所有这些很多进程?我正在考虑检查角度是否大于90°,​​180°等将花费4次。 – Griffin 2011-06-17 03:21:37

+0

它不是一个巨大的节省,但是在你的代码中,你既做了任务,也做了比较,这将它简化为比较和单个任务,并减少了比较次数。在你的每一次比较中,每次都进行比较,而在这里进一步的比较只有在前一次是错误的时候才会进行。就速度而言,在一个紧密的循环中它会加起来。比较比分配要快,因此减少分配和比较将节省一些时间(可能会忽略不计),并且(对我而言)更清晰以限制分配(特别是在调试时) – pstrjds 2011-06-17 15:46:07