2010-07-30 16 views
5

Sto provando a creare un corpo dinamico che orbita intorno a un corpo statico in Box2D. Ho un mondo a gravità zero e un DistanceJoint che collega i due corpi. Ho rimosso tutto l'attrito e lo smorzamento dai corpi e dall'articolazione e sto applicando una velocità lineare iniziale al corpo dinamico. Il risultato è che il corpo inizia l'orbita, ma la sua velocità diminuisce nel tempo - cosa che non mi aspetto in un ambiente a gravità zero senza attrito.Velocità decrescente in assenza di gravità box2d world

Sto facendo qualcosa di sbagliato? La velocità lineare dovrebbe essere ricreata ad ogni passo, o posso delegare questo lavoro a Box2D?

Ecco il codice rilevante:

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

risposta

6

Fisicamente, lei ha ragione. La conservazione dell'energia dovrebbe garantire che la velocità del corpo rimanga costante.

Tuttavia, Box2D non può rappresentare perfettamente la fisica. Ci sarà un piccolo errore in ogni frame e questi errori si sommano. Non so come Box2D gestisca le articolazioni, ma se proietta la posizione dell'oggetto su un cerchio, ciò farebbe sì che la distanza percorsa durante un fotogramma sia leggermente più piccola di quanto sarebbe stata senza il giunto.

Bottom line: non è ragionevole aspettarsi che la velocità rimanga esattamente uguale a quella con cui si è iniziato, e sarà necessario compensare. A seconda delle esigenze, è possibile impostare manualmente la velocità manualmente su ciascun fotogramma o utilizzare una giunzione revoluta, ancorata al pianeta, con un motore.

+0

grazie per la spiegazione! ha davvero senso, quando ci si pensa in termini di informatica, con tutti gli errori di arrotondamento ... Suppongo che mi stavo semplicemente aspettando fisica pura :) –

0

provare a verificare i numeri linearDamping e angularDamping e renderli zero. Questo potrebbe risolvere il problema