我曾经通过制作一个圆形传感器来制作一个旋转平台,该传感器将圆形矢量场给定的切向速度变化应用于物体。我使用的圆形矢量场是这样的:
V = (y, -x)
可以在此处找到该向量场的直观表示:
y 和 x 是身体与传感器中心的相对位置,因此您可以执行以下操作:
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;
}
然后在我的程序的更新方法上我做了这样的事情:
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()));
}
}
这个解决方案有很多解决方法,例如,我不使用脉冲并手动更改速度,它对我来说效果更好。另外,我使用一个常数来解释损耗。
它仍然产生了我需要的效果,所以我希望它对你有用。对于漩涡,我想你只需要连接一个关节,比如鼠标关节,连接到中心并抓住身体。如果仅使用关节,则很难使其强度足以抓住身体,但又不足以使其绕中心旋转。与我的代码一起,通过使用常量可能更容易实现这一点。
我希望这有帮助。
编辑:我刚刚记得,使用平台代码还可以确保旋转方向,而仅使用关节是不可能的。