2012-04-05 2 views
2

Мне нужно создать форму эллипса для тела, и не понимаю, как это сделать в box2d.Как создать формы эллипса в box2d?

Любые идеи, как это сделать не с помощью b2PolygonShape с большим количеством вершин.

+2

В одной из этих демонстраций есть яйцевидная фигура, возможно, вы можете проверить, как он это сделал: http://www.sideroller.com/wck/ – iforce2d

+1

«Определяет« растяжимый »круг. Если высота и ширина одинакова, используется обычная форма круга, в противном случае создается многоугольное приближение ». Это от документации мирового строительного комплекта. Я надеялся, что они сделали что-то новое ... – Pavel

+0

Я отправил ответ ... извините, потребовалось некоторое время ... нужно было немного подумать ... – FuzzyBunnySlippers

ответ

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, с которым вам нужно использовать несколько приборов для определения эллипса. Кроме того, какова точка круга в любом случае? Просто установите массу прямо и выбросьте полностью неиспользованную форму круга. –

+0

Если вы читаете заметки в Box2dCode, говорится: «Вы не можете увеличить это слишком сильно, потому что b2BlockAllocator имеет максимальный размер объекта». для определения b2_maxPolygonVertices. Кроме того, вы можете установить объекты как «пули» и использовать фиксированные временные шаги, чтобы сократить вероятность туннеля. Никакое решение не идеально. Но это должно сработать. – FuzzyBunnySlippers

+0

Может быть, вам не нужен круг ... Я думал, вы не можете установить массу для формы цепи ... Я проверю это. – FuzzyBunnySlippers

Смежные вопросы