gpt4 book ai didi

c++ - 如何在 Box2D 中创建橡胶线?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:00:14 24 4
gpt4 key购买 nike

使用 Box2d,如何创建像 Parachute Ninja (ZeptoLab) 这样的橡胶线(橡皮筋/弹力绳) ?

enter image description here

-(void) CreateElasticRope {
//=======Params
// Position and size
b2Vec2 lastPos = b2Vec2(4,4); //set position first body
float widthBody = 0.35;
float heightBody = 0.1;
// Body params
float density = 0.05;
float restitution = 0.5;
float friction = 0.5;
// Distance joint
float dampingRatio = 0.85;
float frequencyHz = 10;
// Rope joint
float kMaxWidth = 1.1;
// Bodies
int countBodyInChain = 10;
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;
lastPos += b2Vec2(2*widthBody, 0); //modify b2Vect for next body
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) {
//Create distance joint
b2DistanceJointDef distJDef;
b2Vec2 anchor1 = prevBody->GetWorldCenter();
b2Vec2 anchor2 = body->GetWorldCenter();
distJDef.Initialize(prevBody, body, anchor1, anchor2);
distJDef.collideConnected = false;
distJDef.dampingRatio = dampingRatio;
distJDef.frequencyHz = frequencyHz;
world->CreateJoint(&distJDef);

//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;
world->CreateJoint(&rDef);

} //if k>0

prevBody = body;
} //for -loop
}

我使用distance和rope Joints,设置了不同的参数dampingRatio和frequencyHz的值,但是效果远不是一个例子(我的线程很长时间都处于原始状态,并且没有那么有弹性。)。

最佳答案

您可以通过施加力来模拟 Spring 。在每个时间步更新连接的物体上的力(必要时也唤醒物体)。如果其中一个物体是地面(或静态物体),那么您不需要对地面施加任何力,只需对动态物体施加力即可。

普通 Spring 会根据挠度同时施加拉力和压力(拉力和推力)。在你的情况下,你有一个蹦极,所以不会有压缩力只有张力(拉)。

这是您需要的公式:

F = K * x

其中 F 是力,K 是 Spring 刚度(力/挠度),x 是挠度。挠度计算为初始长度和当前长度(连接点之间的距离)之间的差值。 F 的符号决定它是拉还是推。计算 F 后,您需要沿着连接两个 Spring 连接点的线应用它。为了满足力平衡,您需要在相反的方向上施加此力(一个物体获得正力,另一个物体获得负力)。这是因为牛顿爵士是这么说的。

这是一个示例(适用于 pyBox2D,但您可以轻松地将其转换为 C++)

您需要具有某些属性的 Spring 对象。您的 Spring 对象需要知道它们的初始长度、刚度、body1、body2、连接坐标(b1x、b1y、b2x、b2y(在局部坐标中))

在您的情况下,您需要检查长度是否 < spr.initialLength,如果这是 True,则您不施加任何力。

            body1 = spr.box2DBody1
body2 = spr.box2DBody2

pA = body1.GetWorldPoint(b2Vec2(spr.box2Db1x, spr.box2Db1y))
pB = body2.GetWorldPoint(b2Vec2(spr.box2Db2x, spr.box2Db2y))
lenVector = pB - pA
length = lenVector.Length()
deltaL = length - spr.initialLength
force = spr.K * deltaL
#normalize the lenVector
if length == 0:
lenVector = b2Vec2(0.70710678118654757, 0.70710678118654757)
else:
lenVector = b2Vec2(lenVector.x / length, lenVector.y / length)
sprForce = b2Vec2(lenVector.x * force, lenVector.y * force)
body1.ApplyForce(sprForce, pA)
body2.ApplyForce(-sprForce, pB)

关于c++ - 如何在 Box2D 中创建橡胶线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9192672/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com