Make a Vortex in Box2D

后端 未结 2 1339
灰色年华
灰色年华 2021-01-07 02:44

I\'m trying to make a spiral vortex in Box2D on C++ / Objective C by applying forces. What I would like to realize is a vortex that pushes the bodies from a point, or that

2条回答
  •  隐瞒了意图╮
    2021-01-07 03:11

    I created a series of rotating asteroids around a central point by using a distance joint to each asteroid and then applying tangential force to make them "swirl" around the center.

    You could replace the distance joint with an actual force pointed towards the center of the vortex. You could also slowly decrease the distance in the distance joint to have the items "spiral" in. I'm going to go with this as it gives you more control over the speed at which items move into the vortex.

    I'm calling "myBodyA" the body that is the center of the vortex.

    From the Box2d Manual:

    b2DistanceJointDef jointDef;
    jointDef.Initialize(myBodyA, myBodyB, worldAnchorOnBodyA, worldAnchorOnBodyB); jointDef.collideConnected = true;
    world->CreateJoint(&jointDef);
    

    You will have to apply some force to your body (let's say it was myBodyB) to get it moving in the right direction so it rotates around myBodyA. This is going to require some math.

    What you want to do is calculate the vector that points perpendicular to the vector pointing from myBodyB to myBodyA. You can do this by finding the vector from myBodyB to myBodyA, normalizing it, taking the skew of it (rotate by PI/2), and then using it as a force direction. Something like:

    // Calculate Tangent Vector
    b2Vec2 radius = myBodyB.GetPosition()-myBodyA.GetPosition();
    b2Vec2 tangent = radius.Skew();
    tangent.Normalize();
    
    // Apply some force along tangent
    myBodyB.ApplyForceToCenter(body->GetMass()*acceleration*vTangent);
    

    If you read this correctly, you can see F = m * a * tangentVector; that is to say, you are applying force in the direction of the tangent. I believe it will rotate it clockwise (if I did the math right). Regardless, a negative on the force will move it in the opposite direction.

    To stop the body rotating, you can use the SetLinearDamping(dampingValue) on it. So as long as you apply force, it will continue to rotate. If you stop applying force, it should gently stop. You can control the speed up/slow down by the acceleration value and the dampingValue parameters.

    If you really want good control over the speed, I believe you can do this to clamp the speed:

    b2Vec2 linVel = myBodyB.GetLinearVelocity();
    linVel.Normalize();
    linVel *= maxSpeed;
    myBodyB.SetLinearVelocity(linVel);
    

    Was this helpful?

提交回复
热议问题