# Box2D v2.3.0 用户指南（第四章）

﻿﻿

4.1简介

4.2形状

Box2D形状的基类为b2Shape，基类提供了下面几类方法：

·  测试一个点是否和形状重叠（点在形状上）

·  对形状做射线投射（ray cast）

·  计算形状的AABB（axis aligned boundingbox，能够恰好包住形状并且各个边均与坐标轴（之一）平行的四边形）

·  计算形状的质量

·  当一个形状没有附加到物体上时，你可以看到它的顶点在世界坐标系中。

·  当一个形状附加到物体上以后，你可以看到它的顶点在本地坐标系中了。

b2CircleShape circle;

circle.m_p.Set(2.0f, 3.0f);

circle.m_radius = 0.5f;

//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, 0.1f);

int32 count = 3;

b2PolygonShape polygon;

polygon.Set(vertices, count);

void SetAsBox(float32 hx, float hy);

void SetAsBox(float32 hx, float hy, const b2Vec2& center,float32 angle);

//This an edge shape

b2Vec2 v1(0.0f, 0.0f);

b2Vec2 v2(1.0f, 0.0f);

b2EdgeShape edge;

edge.Set(v1, v2);

//This is an edge shape with ghost vertices.

b2Vec2 v0(1.7f, 0.0f);

b2Vec2 v1(1.0f, 0.25f);

b2Vec2 v2(0.0f, 0.0f);

b2Vec2 v3(-1.7f, 0.4f);

b2EdgeShape edge;

edge.Set(v1, v2);

edge.m_hasVertex0 = true;

edge.m_hasVertex3 = true;

edge.m_vertex0 = v0;

edge.m_vertex3 = v3;

//This is a chain shape with isolated vertices

b2Vec2 vs[4];

vs[0].Set(1.7f, 0.0f);

vs[1].Set(1.0f, 0.25f);

vs[2].Set(0.0f, 0.0f);

vs[3].Set(-1.7f, 0.4f);

b2ChainShape chain;

chain.CreateChain(vs, 4);

//Install ghost vertices

chain.SetPrevVertex(b2Vec2(3.0f, 1.0f));

chain.SetNextVertex(b2Vec2(-2.0f, 0.0f));

//Create a loop. The first and last vertices are connected.

b2ChainShape chain;

chain.CreateLoop(vs, 4);

//Visit each child edge

for (int32 i = 0; i < chain.GetChildCount(); ++i)

{

b2EdgeShape edge;

chain.GetChildEdge(&edge, i);

}

4.3一元的几何查询（unarygeometric queries）

b2Transform transform;

transform.SetIdentity();

b2Vec2 point(5.0f, 2.0f);

bool hit = shape->TestPoint(transform, point);

b2Transform transform;

transform.SetIdentity();

b2RayCastInput input;

input.p1.Set(0.0f, 0.0f, 0.0f);

input.p2.Set(1.0f, 0.0f, 0.0f);

input.maxFraction = 1.0f;

int32 childIndex = 0;

b2RayCastOutput = output;

bool hit = shape->RayCast(&output, input, transform,childIndex);

if (hit)

{

b2Vec2 hitPoint = input.p1 +output.fraction * (input.p2–input.p1);

}

（注：input参数中，p1和p2点定义了射线的方向，maxFraction则决定了射线段的长度，也就是定义了在这个射线上多长的范围内来进行射线投射，如果这个值设置的较小，有可能得不到任何交点，如下图所示）

4.4二元方法

·  重叠（overlap）

·  接触取样（contact manifold）

·  距离（distance）

·  碰撞时间（time of impact）

b2Transform xfA = …, xfB = …;

bool overlap = b2TestOverlap(shapeA, indexA, shapeB, indexB, xfA,xfB);

Box2D提供了用于计算重叠对象的接触点（contactpoint）的方法，如果我们圆形-圆形或者圆形-多边形接触，我们只能够得到一个接触点和法线。当多边形和多边形接触时，我们计算得到2个接触点，这些点具有相同的法向量，因此Box2D将他们用一个结构体组装起来。接触解析器（contactsolver）利用可以利用这个方法保证堆叠对象的稳定性。

b2Manifold结构体定义了一个法向量和至多两个接触点，法向量和接触点使用的是本地坐标，为了给接触解析器提供方便，每个接触点都存储了法向和切向（摩擦）冲量。

b2Manifold中的数据被优化以便内部使用，如果你需要使用这些数据，最好是使用b2WorldManifold结构体来生成符合世界坐标系的法向量和接触点。你需要提供一个b2Manifold结构体，一个形状和变换（transform）和半径。

b2WorldManifold worldManifold;

worldManifold.Initialize(&manifold, transformA, shapeA.m_radius,transform, shapeB.m_radius);

for (int32 i = 0; i < manifold.pointCount; i++)

{

b2Vec2 point = worldManifold.points[i];

}

b2PointState state1[2], state2[2];

b2GetPointStates(state1, state2, &manifold1, &manifold2);

if (state1[0] == b2_removeState)

{

//process event

}

b2Distance方法可以用来计算两个形状之间的距离。这个方法要求两个形状都转换为b2DistanceProxy类，对于大量的计算，在计算之前还需要初始化一些缓存对象，具体的细节请参阅b2Distance.h文件。

b2TimeOfImpact方法用来计算两个形状的碰撞时间，称为timeof impact（TOI），b2TimeOfImpact主要是用来防止穿透现象的产生，尤其是防止运动物体穿出静态的几何体跑到外面去。

（解释一下两幅图：上面一幅图中，第一幅图t=0的时候，物体要向t=1的位置旋转，由于t=1时发生了碰撞，因此，碰撞被检测到了，下面的一幅图，t=0和t=1时刻均没有发生碰撞，导致碰撞没有被检测到）

4.5动态树（dynamictree）

Box2D中用b2DynamicTree类来有效地组织大量的形状。这个类并不知道任何形状，它只是通过用户指针来操作形状的AABB（axis-alignedbounding box，前面做了解释）。

4.6 Broad-phase

﻿﻿
• 本文已收录于以下专栏：

举报原因： 您举报文章：Box2D v2.3.0 用户指南（第四章） 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)