在Box2D中做一个漩涡 [英] Make a Vortex in Box2D

查看:246
本文介绍了在Box2D中做一个漩涡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C ++ / Objective C上通过应用力在Box2D中制作螺旋涡旋。
我想实现的是一个涡流,从一个点推动身体,或吸引他们。
我想我将不得不应用一个以上的力。



我的入口点在这个问题是:



我想我必须应用3力:
- 从中​​心吸引或排斥身体的冲动。
- 使它在螺旋上横向移动的冲动,但是...怎么样?
- 转动身体本身的力矩,如果冲动不为我做。

解决方案

我曾经做过一个旋转平台,使圆形传感器对圆形矢量给出的切线速度变化领域。我使用的圆形矢量字段是:

  V =(y,-x)

这个向量字段的视觉表示可以在这里找到:
http://kasadkad.files.wordpress.com/2009/09/derham1.png?w=450& h = 427



y和x是物体与传感器中心的相对位置,因此可以这样做:

 向量getTangentVector(向量relativePosition,bool invert)
{
Vector vec;
if(invert)//如果是cw或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-> gt; contact;

if(c-> IsTouching())
{
const b2Body * bodyA = c-> GetFixtureA() - > GetBody
const b2Body * bodyB = c-> GetFixtureB() - > GetBody();

const b2Body * targetBody =(bodyA == platformBody)?bodyB:bodyA;

矢量速度= getTangentImpulse(
getRelativePosition(platformBody,targetBody),
true);


speed * = CONSTANT; // CONSTANT = 1.8,
//这是为了考虑targetBody的流失,
//所以它不会在平台上滑动

vector currentSpeed;
currentSpeed.setX(targetBody-> GetLinearVelocity()。x);
currentSpeed.setY(targetBody-> GetLinearVelocity()。y);



矢量diff = speed - currentSpeed;
diff * = 0.01; //应该依赖于时间,但这工作很好。它使得
// body的线速度与
//0.01变化率下的speed相同。

currentSpeed + = diff;
targetBody-> SetLinearVelocity(
b2Vec2(currentSpeed.x(),
currentSpeed.y()));

}

}

很多在这个解决方案的解决方法,例如,我不使用脉冲和手动更改速度,它为我工作更好。此外,我使用常数来计算磨损。



仍然产生了我需要的效果,所以我希望它为你工作。对于涡流我想你只需要连接一个关节,像鼠标关节,附加到中心和抓住身体。如果你只使用关节,它将很难使它足够抓住身体,但足够弱,使其围绕中心旋转。与我的代码一起,它可能更容易实现这只是通过玩弄常数。



我希望这有助于。



编辑:我只是记得,使用平台代码,你也确保旋转的方向,这是不可能只与关节。


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 attract them. I guess I'll have to apply more than one force.

My entry point in this problem is :

I think I have to apply 3 forces : - An impulse to attract or repulse the body from the center. - An impulse to make it move laterally on a spiral, but... how ? - A torque to rotate the body itself if the impulse don't do it for me.

解决方案

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.

这篇关于在Box2D中做一个漩涡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆