Vous utilisez la fonction «Set ()» du polygone Box2D?

11

J'utilise le moteur physique Box2D. Et il existe un type de forme pour box2D appelé b2PolygonShape.

Dans cette classe, vous pouvez créer des polygones. Il existe également une fonction Set () qui prend un tableau de points et un nombre de sommets.

Box2D a un exemple comme celui-ci:

// This defines a triangle in CCW order.

b2Vec2 vertices[3];

vertices[0].Set(0.0f, 0.0f);

vertices[1].Set(1.0f, 0.0f);

vertices[2].Set(0.0f, 1.0f);

int32 count = 3;



b2PolygonShape polygon;

polygon.Set(vertices, count);

Cela marche. Pourtant, quand j'ai essayé de pratiquer et de jouer avec cette fonction, j'ai fait ceci:

  b2Vec2 vertices[4];

  vertices[0].Set(0, 0);
  vertices[1].Set(0,10);
  vertices[2].Set(10,10);
  vertices[3].Set(10,0);

  int32 count = 4;

  b2PolygonShape polygon;

  polygon.Set(vertices, count);

Lorsque j'ai compilé et exécuté cela, il s'est écrasé après la fonction Set (). Cela ne créerait-il pas un carré?

Aussi dans la console, j'ai obtenu ceci:

Assertion failed: s > 0.0f

Qu'ai-je fait de mal?

xAustechx
la source

Réponses:

10

C'est parce que les quatre sommets que vous avez fournis sont dans le sens horaire et Box2D suppose qu'ils sont dans le sens antihoraire, comme dans votre premier exemple. Cela devrait donc fonctionner correctement si vous le changez en:

  b2Vec2 vertices[4];

  vertices[0].Set(0, 0);
  vertices[1].Set(10,0);
  vertices[2].Set(10,10);
  vertices[3].Set(0,10);

  int32 count = 4;

  b2PolygonShape polygon;

  polygon.Set(vertices, count);

Et en passant, si vous créez simplement un polygone en forme de boîte, vous pouvez utiliser la fonction de commodité

void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)
Noel Llopis
la source
Existe-t-il un moyen de faire en sorte qu'il ne suppose pas? Ce que j'essaie de faire, c'est de créer un programme où vous pouvez simplement dessiner des formes, un peu comme PHUN. Et c'est là que je suis arrivé à ces erreurs, j'ai donc décidé de l'essayer avec le rectangle.
xAustechx
1
Pas vraiment. Les polygones doivent être convexes et doivent donc assumer l'ordre d'enroulement pour le vérifier. Si vous allez dessiner et créer des polygones à la volée, vous devez les pré-traiter pour vous assurer qu'ils sont sous la limite du nombre de sommets (je pense que c'est 6 ou 8 verts) et à ce stade, vous pourriez aussi bien les enrouler correctement avant de les remettre à Box2D.
Noel Llopis
0

Vous pouvez déterminer l'enroulement du polygone, puis l'inverser s'il est dans le sens inverse des aiguilles d'une montre.

Une méthode courante consiste à calculer l'aire du polygone à l'aide de l'algorithme ci-dessous. Il renverra un nombre + ve pour le remontage dans le sens horaire et un nombre -ve pour le remontage dans le sens inverse des aiguilles d'une montre.

Voici un exemple Python:

def poly_area(verts):
    """
    Return area of a simple (ie. non-self-intersecting) polygon.
    Will be negative for counterclockwise winding.
    """
    accum = 0.0
    for i in range(len(verts)):
        j = (i + 1) % len(verts)
        accum += verts[j][0] * verts[i][1] - verts[i][0] * verts[j][1]
    return accum / 2
DrDeth
la source