2012-04-05 144 views
2

我需要为body创建椭圆形状,并且不知道如何在box2d中创建椭圆形状。如何在box2d中创建椭圆形状?

任何想法如何做到这一点通过使用b2PolygonShape有很多顶点的

+2

在这些演示中有一个蛋形,也许你可以看看他是怎么做到的:http://www.sideroller.com/wck/ – iforce2d 2012-04-06 17:36:29

+1

“定义一个”可拉伸“的圆圈,如果高度和宽度相同,则使用规则的圆形形状,否则将创建多边形近似。“ 它来自世界建筑工具包的文件。我希望他们完成水渍... – Pavel 2012-08-13 15:07:52

+0

我发布了一个答案...对不起,它花了一段时间...不得不想一点... – FuzzyBunnySlippers 2013-12-13 02:22:28

回答

5

**选项1 **

利用一款机身搭配两场比赛:第一是中央圆形给身体一些质量。第二个是椭圆形,顶点由链状构成。

第一个夹具可以使您的身体像一个有质量的身体一样行动,而第二个夹具可以让您正确处理碰撞。

我最近做了一个轮盘赌的例子。我发布了下面的代码来创建它。将椭圆的常数值(OUTER_RADIUS)替换为椭圆的极坐标形式found here on wikipedia

void MainScene::CreateBody() 
{ 
    const float32 INNER_RADIUS = 2.50; 
    const float32 OUTER_RADIUS = 3.0; 
    const float32 BALL_RADIUS = 0.1; 
    const uint32 DIVISIONS = 36; 

    Vec2 position(0,0); 

    // Create the body. 
    b2BodyDef bodyDef; 
    bodyDef.position = position; 
    bodyDef.type = b2_dynamicBody; 
    _body = _world->CreateBody(&bodyDef); 
    assert(_body != NULL); 

    // Now attach fixtures to the body. 
    FixtureDef fixtureDef; 
    fixtureDef.density = 1.0; 
    fixtureDef.friction = 1.0; 
    fixtureDef.restitution = 0.9; 
    fixtureDef.isSensor = false; 

    // Inner circle. 
    b2CircleShape circleShape; 
    circleShape.m_radius = INNER_RADIUS; 
    fixtureDef.shape = &circleShape; 
    _body->CreateFixture(&fixtureDef); 

    // Outer shape. 
    b2ChainShape chainShape; 
    vector<Vec2> vertices; 
    const float32 SPIKE_DEGREE = 2*M_PI/180; 
    for(int idx = 0; idx < DIVISIONS; idx++) 
    { 
     float32 angle = ((M_PI*2)/DIVISIONS)*idx; 
     float32 xPos, yPos; 

     xPos = OUTER_RADIUS*cosf(angle); 
     yPos = OUTER_RADIUS*sinf(angle); 
     vertices.push_back(Vec2(xPos,yPos)); 
    } 
    vertices.push_back(vertices[0]); 
    chainShape.CreateChain(&vertices[0], vertices.size()); 
    fixtureDef.shape = &chainShape; 
    _body->CreateFixture(&fixtureDef); 

} 

您还可以检查出this post的轮盘赌(加图片善良)的解决方案。

选项#2 除了使用链条/边缘形状,您可以创建一个夹具的三角形风扇。一旦你有椭圆的顶点,你可以做类似的事情:

b2Vec2 triVerts[3]; 
triVerts[0] = Vec2(0,0); 
for(int idx = 1; idx < vertices.size(); idx++) 
{ 
    b2PolygonShape triangle; 
    fixtureDef.shape = &triangle; 
    // Assumes the vertices are going around 
    // the ellipse clockwise as angle increases. 
    triVerts[1] = vertices[idx-1]; 
    triVerts[2] = vertices[idx]; 
    triangle.Set(triVerts,3); 
    _body->CreateFixture(&fixtureDef); 
} 

对您有帮助吗?

+0

这样的声音应该更容易出现问题(东西可以更容易隧道内如果基于多边形的主体是单个多边形夹具,则该链条会卡住多边形的“接缝”,并且不存在“接缝”),并且不如使用完全相同的链几何体定义多边形那样优雅。尽管如此,还是有b2_maxpolygonvertices限制要解决,超过此限制,您需要使用多个固定装置来定义椭圆。此外,无论如何,这个圈子的重点是什么?直接设置质量并丢弃完全未使用的圆形。 – 2013-12-13 02:28:19

+0

如果您阅读Box2dCode中的注释,说:“您不能增加太多,因为b2BlockAllocator具有最大的对象大小。”为b2_maxPolygonVertices定义。此外,您可以将对象设置为“项目符号”,并使用固定的时间步骤来减少隧道可能性。没有解决方案是完美的但这应该工作。 – FuzzyBunnySlippers 2013-12-13 02:37:14

+0

也许你不需要这个圆圈......我以为你无法为连锁形状设置质量...我会检查一下。 – FuzzyBunnySlippers 2013-12-13 02:39:13