2011-06-17 6 views
0

Question révoquées par l'affiche originaleproblèmes avec les calculs de mouvement circulaire

Hé donc lors de l'exécution du code suivant ma place est censé voyager dans un cercle, mais il y a une sorte de problème avec la fonction qui calcule la x, y mouvement qui devrait se produire en fonction de la vitesse et de l'angle de déplacement.

Il se déplace avec succès autour et autour, mais pas dans le bon sens. le 2ème et le 4ème quadrant sont en quelque sorte inversés et s'incurvent vers le centre du cercle plutôt que vers l'extérieur.

Je ne peux pas comprendre quel est le problème ... quelqu'un veut aider?

#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(); 
    } 

} 

Répondre

0

Il semble que je me suis trompé en supposant que le triangle formé et utilisé pour calculer le mouvement nécessaire pour atteindre les coordonnées x, y utilisera toujours automatiquement l'axe Y comme du côté opposé de la « Angle », et Bien que les coordonnées aient été inversées pour les Quadrants 2 et 4, merci pour les autres commentaires!

Voici le code mis à jour:

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

en faisant 90 Angle Je change les angles utilisés pour trouver le X et Y côté du triangle imaginaire ....

4

Votre première erreur:

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

devrait être:

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

Je ne suis pas sûr de savoir pourquoi vous allez la peine de diviser l'angle en quarts de cercle. Pensez-vous que la fonction sin n'est définie que pour la plage de 0 à 90 degrés?

+0

si je peux plus tard faire le mouvement x et y négatif ou positif basé sur le quadrant est – Griffin

+1

@Griffin, les fonctions sin (et cos) fournira automatiquement des nombres négatifs pour les angles appropriés. –

0

Je ne sais pas tous les problèmes, mais cette ligne de code est erroné:

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

Si Angle < 0 puis 360 - Angle sera> 360

vous pouvez également nettoyer le code de réglage de quadrant, sinon, lorsque l'angle est> 270, vous effectuez l'assignation 4 fois.

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

nettoierait le code de réglage de quadrant sauver tout ce processus? Je pensais en passant par le processus de vérifier si l'angle est plus grand que 90, 180 etc. prendrait juste aussi longtemps qu'assigner 4 fois. – Griffin

+0

Ce n'est pas une énorme économie, mais dans votre code vous faites à la fois la tâche et la comparaison, cela réduit à la comparaison et une seule affectation et réduit le nombre de comparaisons. Dans le vôtre, chaque comparaison est faite à chaque fois, alors que les comparaisons ultérieures ne sont faites que si la précédente était fausse. En ce qui concerne la vitesse, dans une boucle serrée, cela s'ajouterait. Une comparaison est plus rapide qu'une affectation, donc réduire les affectations ainsi que les comparaisons va faire gagner du temps (peut être négligeable) et (pour moi) c'est plus propre à limiter les affectations (surtout lors du débogage) – pstrjds

Questions connexes