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
I once did a rotating platform by making a circular sensor which applied a tangential speed change to the body given by a circular vector field. The circular vector field which I used was this:
V = (y, -x)
A visual representation of this vector field can be found here: http://kasadkad.files.wordpress.com/2009/09/derham1.png?w=450&h=427
The y and x are the relative position of the body to the centre of the sensor, so you can do something like this:
Vector getTangentVector(Vector relativePosition, bool invert)
{
Vector vec;
if(invert) //if it's cw or ccw
{
vec.setY(relativePosition.x());
vec.setX(-relativePosition.y());
}
else
{
vec.setY(-relativePosition.x());
vec.setX(relativePosition.y());
}
return vec;
}
Then on the update method of my program I do something like this:
for (b2ContactEdge* ce = platformBody->GetContactList(); ce; ce = ce->next)
{
b2Contact* c = ce->contact;
if(c->IsTouching())
{
const b2Body* bodyA = c->GetFixtureA()->GetBody();
const b2Body* bodyB = c->GetFixtureB()->GetBody();
const b2Body* targetBody = (bodyA == platformBody)?bodyB:bodyA;
Vector speed = getTangentImpulse(
getRelativePosition(platformBody, targetBody),
true);
speed *= CONSTANT; // CONSTANT = 1.8,
// this is to account for the targetBody attrition,
// so it doesn't slip on the platform
Vector currentSpeed;
currentSpeed.setX(targetBody->GetLinearVelocity().x);
currentSpeed.setY(targetBody->GetLinearVelocity().y);
Vector diff = speed - currentSpeed;
diff *= 0.01; //should depend on time, but this worked nicely. It makes the
//body change its linear velocity to be the same as "speed" at a
//0.01 change rate.
currentSpeed += diff;
targetBody->SetLinearVelocity(
b2Vec2(currentSpeed.x(),
currentSpeed.y()));
}
}
There are a lot of workarounds in this solution, for example, I don't use impulses and manually change the speed, it worked better for me. Also, I use a constant to account for attrition.
Still it produced the effect that I needed so I hope it works for you. For the vortex I guess you just need to connect a joint, like a mouse joint, attached to the centre and grabbing the body. If you use just the joint, it will be hard to make it strong enough to grab the body, but weak enough to make it rotate around the centre. Together with my code it might be easier to achieve this just by playing around with the constants.
I hope this helps.
edit: I just remembered that, with the platform code you also ensure the direction of the rotation, which is not possible with just the joint.