我正在尝试使用b2Box模拟与铰链连接的两个物体(我使用b2RevoluteJoint
)的行为。这是两个对象在一开始的相对(重叠)位置。
它们都有一个红点(它们位于相同的全局坐标处)。我希望较长的物体围绕这个点旋转。这是代码(anchorView
是小方块,rotorView
是长棍子):
- (void)viewDidLoad {
[super viewDidLoad];
UIView *anchorView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 30, 30)];
anchorView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.2];
UIView *anchorDot = [[UIView alloc] initWithFrame:CGRectMake(13, 13, 4, 4)];
anchorDot.backgroundColor = [UIColor redColor];
[self.view addSubview:anchorView];
[anchorView addSubview:anchorDot];
UIView *rotorView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 300, 30)];
rotorView.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.2];
UIView *rotorDot = [[UIView alloc] initWithFrame:CGRectMake(13, 13, 4, 4)];
rotorDot.backgroundColor = [UIColor redColor];
[self.view addSubview:rotorView];
[rotorView addSubview:rotorDot];
b2Vec2 gravity; gravity.Set(0.0f, -9.81f);
world = new b2World(gravity);
world->SetContinuousPhysics(true);
// Static anchor
b2BodyDef anchor;
anchor.position.Set(anchorView.center.x / PTM, (1004.0 - anchorView.center.y) / PTM);
anchor.type = b2_staticBody;
b2Body* anchorBody = world->CreateBody(&anchor);
b2PolygonShape anchorBox;
anchorBox.SetAsBox(anchorView.frame.size.width / PTM / 2.0, anchorView.frame.size.height / PTM / 2.0);
anchorBody->CreateFixture(&anchorBox, 0.0);
// Dynamic rotor
b2BodyDef rotor;
rotor.position.Set(rotorView.center.x / PTM, (1004.0 - rotorView.center.y) / PTM);
rotor.type = b2_dynamicBody;
b2Body *rotorBody = world->CreateBody(&rotor);
b2PolygonShape rotorBox;
rotorBox.SetAsBox(rotorView.frame.size.width / PTM / 2.0, rotorView.frame.size.height / PTM / 2.0);
rotorBody->CreateFixture(&rotorBox, 0.0);
rotorView.tag = (int)rotorBody;
// Joint
b2RevoluteJointDef jointDef;
jointDef.Initialize(anchorBody, rotorBody, anchorBody->GetWorldCenter());
world->CreateJoint(&jointDef);
// doing stuff
rotorBody->SetAngularVelocity(5.0);
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 / 30.0 target:self selector:@selector(onTimer:) userInfo:rotorView repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}
- (void)onTimer:(NSTimer *)theTimer {
int32 velocityIterations = 8;
int32 positionIterations = 1;
UIView *rotorView = [theTimer userInfo];
b2Body *rotorBody = (b2Body *)rotorView.tag;
world->Step(0.3f / 60.0f, velocityIterations, positionIterations);
CGFloat angle = rotorBody->GetAngle();
b2Vec2 c = rotorBody->GetWorldCenter();
rotorView.center = CGPointMake(c.x * PTM, 1004.0 - c.y * PTM);
CGAffineTransform rt = CGAffineTransformMakeRotation(angle);
rotorView.transform = rt;
}
开始这之后,我得到了一种不同类型的动作。这是它的样子(为了澄清,我添加了几个笔画):
更确切地说,红点不是绑在一起,但是身体中心之间的距离总是保持不变,好像有一根绳子在我画了虚线。
如果我查看调试器中的jointDef.localAnchorB
,它包含长棒坐标系中红点的右坐标。我做错了什么?
答案 0 :(得分:0)
解决。这一切都与这两条线有关:
CGFloat angle = rotorBody->GetAngle();
和
CGAffineTransform rt = CGAffineTransformMakeRotation(angle);
Box2D和Cocoa Touch使用不同的方向来计算旋转角度,因此它必须是:
CGAffineTransform rt = CGAffineTransformMakeRotation(-angle);