2010-07-30 19 views
5

J'essaye de créer un corps dynamique qui orbite autour d'un corps statique dans Box2D. J'ai un monde d'apesanteur, et un DistanceJoint qui relie les deux corps. J'ai enlevé tout frottement et tout amortissement des corps et de l'articulation, et j'applique une vitesse linéaire initiale au corps dynamique. Le résultat est que le corps commence à orbiter, mais sa vitesse diminue avec le temps - ce que je n'attends pas dans un environnement de gravité nulle sans friction.Diminuer la vitesse dans l'apesanteur box2d monde

Est-ce que je fais quelque chose de mal? La vitesse linéaire devrait-elle être recréée à chaque étape, ou puis-je déléguer ce travail à Box2D?

Voici le code correspondant:

// positions of both bodies 

Vector2 planetPosition = new Vector2(x1/Physics.RATIO, y1/Physics.RATIO); 
Vector2 satellitePosition = new Vector2(x2/Physics.RATIO, y2/Physics.RATIO); 


// creating static body 

BodyDef planetBodyDef = new BodyDef(); 
planetBodyDef.type = BodyType.StaticBody; 
planetBodyDef.position.set(planetPosition); 
planetBodyDef.angularDamping = 0; 
planetBodyDef.linearDamping = 0; 

planetBody = _world.createBody(planetBodyDef); 

CircleShape planetShapeDef = new CircleShape(); 
planetShapeDef.setRadius(40); 

FixtureDef planetFixtureDef = new FixtureDef(); 
planetFixtureDef.shape = planetShapeDef; 
planetFixtureDef.density = 0.7f; 
planetFixtureDef.friction = 0; 

planetBody.createFixture(planetFixtureDef); 

// creating dynamic body 

BodyDef satelliteBodyDef = new BodyDef(); 
satelliteBodyDef.type = BodyType.DynamicBody; 
satelliteBodyDef.position.set(satellitePosition); 
satelliteBodyDef.linearDamping = 0; 
satelliteBodyDef.angularDamping = 0; 

satelliteBody = _world.createBody(satelliteBodyDef); 

CircleShape satelliteShapeDef = new CircleShape(); 
satelliteShapeDef.setRadius(10); 

FixtureDef satelliteFixtureDef = new FixtureDef(); 
satelliteFixtureDef.shape = satelliteShapeDef; 
satelliteFixtureDef.density = 0.7f; 
satelliteFixtureDef.friction = 0; 

satelliteBody.createFixture(satelliteFixtureDef); 

// create DistanceJoint between bodies 

DistanceJointDef jointDef = new DistanceJointDef();   
jointDef.initialize(satelliteBody, planetBody, satellitePosition, planetPosition); 
jointDef.collideConnected = false; 
jointDef.dampingRatio = 0; 

_world.createJoint(jointDef); 

// set initial velocity 

satelliteBody.setLinearVelocity(new Vector2(0, 30.0f)); // orthogonal to the joint 

Répondre

6

Physiquement, vous avez raison. La conservation de l'énergie devrait assurer que la vitesse du corps reste constante. Cependant, Box2D ne peut pas parfaitement représenter la physique. Il y aura une petite erreur dans chaque trame, et ces erreurs s'additionnent. Je ne sais pas comment Box2D manipule les articulations, mais si elle projette la position de l'objet sur un cercle, la distance parcourue pendant un cadre serait légèrement plus petite que ce qu'elle aurait été sans l'articulation.

Ligne de fond: il n'est pas raisonnable de s'attendre à ce que la vitesse reste exactement la même que celle avec laquelle vous avez commencé, et vous devrez compenser. En fonction de vos besoins, vous pouvez soit régler manuellement la vitesse de chaque image, soit utiliser un joint rotatif ancré sur la planète avec un moteur.

+0

merci pour l'explication! ça a du sens, quand on y pense en termes d'informatique, avec toutes les erreurs d'arrondis ... Je suppose que je m'attendais simplement à de la pure physique :) –

0

Essayez de vérifier les numéros linearDamping et angularDamping et de les rendre à zéro. Cela pourrait résoudre le problème