2010-07-30 15 views
5

Estoy tratando de crear un cuerpo dinámico que orbite alrededor de un cuerpo estático en Box2D. Tengo un mundo de gravedad cero y un DistanceJoint que conecta los dos cuerpos. He eliminado toda la fricción y la amortiguación de los cuerpos y la articulación, y estoy aplicando una velocidad lineal inicial al cuerpo dinámico. El resultado es que el cuerpo comienza a orbitar, pero su velocidad disminuye con el tiempo, lo que no espero en un entorno de gravedad cero sin fricción.Disminuyendo la velocidad en gravedad cero box2d world

¿Estoy haciendo algo mal? ¿Debería recrearse la velocidad lineal en cada paso, o puedo delegar este trabajo a Box2D?

Este es el código correspondiente:

// 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 

Respuesta

6

Físicamente, son correctas. La conservación de la energía debe garantizar que la velocidad del cuerpo permanezca constante.

Sin embargo, Box2D no puede representar perfectamente la física. Habrá un pequeño error en cada cuadro, y estos errores se suman. No sé cómo Box2D maneja las articulaciones, pero si proyecta la posición del objeto en un círculo, esto provocaría que la distancia recorrida durante un cuadro sea un poco más pequeña de lo que hubiera sido sin la unión.

Conclusión: no es razonable esperar que la velocidad permanezca exactamente igual a la que comenzaste, y tendrás que compensar. Dependiendo de sus necesidades, puede establecer la velocidad manualmente en cada cuadro, o tal vez usar una articulación giratoria, anclada en el planeta, con un motor.

+0

¡gracias por la explicación! realmente tiene sentido, cuando uno lo piensa en términos de ciencia de la computación, con todos los errores de redondeo ... supongo que simplemente esperaba pura física :) –

0

intente comprobar los números linearDamping y angularDamping y ponerlos a cero. Eso podría resolver el problema