如何在box2d中创建椭圆形状?

4

我需要创建椭圆形的物体,但不知道如何在box2d中实现。

有没有什么方法可以做到这一点,而不是使用许多顶点的b2PolygonShape呢?


2
这些演示中有一个蛋形状,也许你可以查看一下他是如何做到的:http://www.sideroller.com/wck/ - iforce2d
1
定义一个“可伸缩”的圆形。如果高度和宽度相同,则使用常规的圆形形状。否则,将创建一个多边形近似值。这是来自世界构建工具包的文档。我希望他们做了些新的东西... - Pavel
我回答了...抱歉花了一些时间...需要思考一下... - FuzzyBunnySlippers
1个回答

6

选项#1

使用一个带有两个固定装置的身体:第一个是中央圆形,用于赋予身体一些质量。第二个是椭圆形,其顶点由链状形状制成。

第一个固定装置使您可以使身体像具有一定质量的身体一样运作,而第二个固定装置将使您能够正确处理碰撞。

我最近为轮盘做了一个示例。 我发布了下面的代码以创建它。 将半径(OUTER_RADIUS)的常数值替换为此处在维基百科上找到的椭圆的极坐标形式。

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);
    
}

您还可以查看此文章,了解轮盘(加上图片)的解决方案。

选项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);
}

这篇文章对您有帮助吗?


听起来这种方法更容易出现问题(物体可以更容易地穿过链条而不是卡在多边形的“接缝”中,而且如果基于多边形的物体是单个多边形夹具,则不存在“接缝”),并且比使用相同的链条几何形状定义多边形要不够优雅。但是,还有b2_maxpolygonvertices限制需要处理,超过该限制需要使用多个夹具来定义椭圆形。此外,圆形的作用是什么?只需直接设置质量并丢弃完全未使用的圆形即可。 - Steven Lu
也许你不需要圆形...我以为你不能为链状形状设置质量...我会查一下的。 - FuzzyBunnySlippers
对于轮盘,无论是否有外链形状,质量都保持不变(19.63...)。 - FuzzyBunnySlippers
你可以使用SetMassData为一个物体显式地设置质量、转动惯量和质心位置。我对使用它有点盲区,因为我喜欢让系统管理这些事情,不想担心当物体被分解、创建或焊接在一起时我改变了什么。我认为三角形扇形可能是最好的解决方案(选项#2)。感谢您的建议。 - FuzzyBunnySlippers
三角形扇形可能比所需的固定装置和冗余几何图形更多。使用“八角形扇形”会使函数稍微复杂一些。 - Steven Lu
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接