Pergunta

I would like to make a scene where there is a "pendulum" that oscillates continuously, no stop. I have uploaded an image for better clarity. So i try to use Box2D joints. For example:

   RevoluteJointDef revDef = new RevoluteJointDef();
     revDef.initialize(ball, box, ball.getWorldCenter());
     revDef.lowerAngle = 0 * MathUtils.degreesToRadians;
     revDef.upperAngle = 180 * MathUtils.degreesToRadians;
     revDef.enableLimit = true;
     revDef.maxMotorTorque = 10.0f;
     revDef.motorSpeed = 2.0f;
     revDef.enableMotor = true;

  revoluteJoint = (RevoluteJoint)world.createJoint(revDef);

But it doesn't work. If i comment limits and motor lines i obtain the same result that i obtain when these lines are uncommented. Although motor is enabled, it seems not work.

P.S. The motor must stop when the user releases the box by press a button. So the box falls to the ground due to the force of gravity.

Can someone help me? Thanks!!

Scene image

Foi útil?

Solução

I don't think you need a revolute joint for this, but a rope joint (b2RopeJoint). A revolute joint will make the two object rotate around a single point. The rope joint will keep one swinging from another like a pendulum.

You need to make the pendulum attach with a single rope joint to a static body. Then cut the rope joint when you want it to fall. If gravity is turned on and you don't have any retarding forces, the pendulum should continue indefinitely (or for a really long time depending on numerics).

Take a look at this post that was just done for something like this. Note that the code is also posted on github here. In that case, there were two extra rope joints added to constrain the body so that it could not move beyond the end of the initial swing. I don't think you need those.

To create the pendulum yourself, use something like:

   // Calculate the local position of the
   // top of screen in the local space
   // of the ground box.
   CCSize scrSize = CCDirector::sharedDirector()->getWinSize();
   b2Vec2 groundWorldPos = b2Vec2((scrSize.width/2)/PTM_RATIO,(scrSize.height)/PTM_RATIO);
   b2Vec2 groundLocalPos = m_pGround->GetLocalPoint(groundWorldPos);

   // Now create the main swinging joint.
   b2RopeJointDef jointDef;
   jointDef.bodyA = m_pGround;
   jointDef.bodyB = body;
   jointDef.localAnchorA = groundLocalPos;
   jointDef.localAnchorB = b2Vec2(0.0f,0.0f);
   jointDef.maxLength = (groundWorldPos-body->GetWorldCenter()).Length();
   jointDef.collideConnected = true;
   world->CreateJoint(&jointDef);

NOTE This is in C++, not java (for libgdx), but the approach should be sound and you just have to map the "->" onto the "." where needed.

In my example, it ended up looking like this (image liberated from other posted answer):

enter image description here

Was this helpful?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top