Box2d: Elastic rope takes time to get back to its initial position

311 Views Asked by At

I am creating a rubber band in Box2d. Here is my code.

// init physics
    [self initPhysics];

    // Create ball body

    CCSprite *ball = [CCSprite spriteWithFile:@"rubberband.png"];
    ball.position = ccp(100, 100);
    ball.tag = 1;
   // [self addChild:ball];

    //=======Params
    // Position and size
    b2Vec2 lastPos = b2Vec2(154.0/PTM_RATIO,65.0/PTM_RATIO); //set position first body
    float widthBody = 2.0/PTM_RATIO;
    float heightBody = 2.0/PTM_RATIO;
    // Body params
    float density = 0.0;
    float restitution = 0.5;
    float friction = 0.5;
    // Distance joint
    float dampingRatio = 0.85;
    float frequencyHz = 10;
    // Rope joint
    float kMaxWidth = 50.0/PTM_RATIO;
    // Bodies
    int countBodyInChain = 68;
    b2Body* prevBody;
    //========Create bodies and joints
    for (int k = 0; k < countBodyInChain; k++) {
        b2BodyDef bodyDef;
        if(k==0 || k==countBodyInChain-1) bodyDef.type = b2_staticBody; //first and last bodies are static
        else bodyDef.type = b2_dynamicBody;
        bodyDef.position = lastPos;

        bodyDef.fixedRotation = YES;
        b2Body* body = world->CreateBody(&bodyDef);

        b2PolygonShape distBodyBox;
        distBodyBox.SetAsBox(widthBody, heightBody);
        b2FixtureDef fixDef;
        fixDef.density = density;
        fixDef.restitution = restitution;
        fixDef.friction = friction;
        fixDef.shape = &distBodyBox;
        body->CreateFixture(&fixDef);

        if(k>0) {
            b2RevoluteJointDef armJointDef;
                        armJointDef.Initialize(prevBody, body, lastPos);
                        armJointDef.enableMotor = true;
            armJointDef.enableLimit = true;
                        armJointDef.maxMotorTorque = 1;
            world->CreateJoint(&armJointDef);

            //Create rope joint
            b2RopeJointDef rDef;
            rDef.maxLength = (body->GetPosition() - prevBody->GetPosition()).Length() * kMaxWidth;
            rDef.localAnchorA = rDef.localAnchorB = b2Vec2_zero;
            rDef.bodyA = prevBody;
            rDef.bodyB = body;
            rDef.collideConnected = false;

            world->CreateJoint(&rDef);

        } //if k>0
        lastPos += b2Vec2(widthBody, 0); //modify b2Vect for next body
        prevBody = body;
    } //for -loop


[self scheduleUpdate];
}
return self;

}

Problem is that when the app starts, rubber band appears in stretched form in U shape and then it gradually start contracting and coming to become straight horizontally. Can anyone please tell me why it is happening? I want the rubber band to be without being stretched in the beginning. Best Regards

1

There are 1 best solutions below

2
On

You don't update lastPos so all bodies occupy the same position initially. Box2D will force them apart and this could lead to the problem.