Box2D射线和AABB碰撞检测
来源:互联网 发布:联邦止咳水 淘宝 编辑:程序博客网 时间:2024/05/14 03:58
box2d使用了一种叫做slab的碰撞检测算法。所谓slab是指两个平行平面之间的空间,由此我们可以把3D空间中的AABB盒子看做是由AABB的3组平行面形成的3个方向的slab的交集。根据这个定义,我们可以得到以下两个结论:
1.如果一个点在AABB中,那么这个点必定同时在这3个slab中。
2.如果一条射线和AABB相交,那么这条射线和3个slab的相交部分必定有重合部分。
这很容易理解,如果射线和3个slab的相交线段没有重合,那么这些线段就不可能同时存在于3个slab中,也就不可能在AABB盒子中。下图展示了2D空间中射线R1和R2与AABB相交的情形。R1在x-slab和y-slab中的线段没有重合部分,因此R1和AABB不相交。R2在x-slab和y-slab中的线段有重合部分,因此R2和AABB相交。
根据上述原理,检查2D中射线和AABB的碰撞,只需要检查射线和x-slab,y-slab的交线是否有重合。
首先我们需要得到射线和slab边界平面的交点。射线可以用参数方程表示为R(t) = P0 + t·d , (其中P0为射线起点,d为射线的方向向量),平面由隐式定义方程X· n = D, (其中X为平面上的点,n为平面法向量,D为原点到平面的距离)给出。将平面方程中的X用P0 + t·d替换解得交点的参数t=(D−P0·n)/(d·n).由于AABB的slab平面都分别和两个坐标轴平行,公式可以进一步简化:设P0=(px,py,pz), d=(dx,dy,dz), t和x-slab面的交点的参数计算公式可化简为t=(D-px)/dx,而此处的D就是AABB的边界面x坐标。
/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). struct b2RayCastInput { b2Vec2 p1, p2; float32 maxFraction; }; /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 /// come from b2RayCastInput. struct b2RayCastOutput { b2Vec2 normal; float32 fraction; }; bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const { float32 tmin = -b2_maxFloat; float32 tmax = b2_maxFloat; b2Vec2 p = input.p1; b2Vec2 d = input.p2 - input.p1; b2Vec2 absD = b2Abs(d); b2Vec2 normal; for (int32 i = 0; i < 2; ++i) { if (absD(i) < b2_epsilon) { // Parallel. if (p(i) < lowerBound(i) || upperBound(i) < p(i)) { return false ; } } else { float32 inv_d = 1.0f / d(i); float32 t1 = (lowerBound(i) - p(i)) * inv_d; float32 t2 = (upperBound(i) - p(i)) * inv_d; // Sign of the normal vector. float32 s = -1.0f; if (t1 > t2) { b2Swap(t1, t2); s = 1.0f; } // Push the min up if (t1 > tmin) { normal.SetZero(); normal(i) = s; tmin = t1; } // Pull the max down tmax = b2Min(tmax, t2); if (tmin > tmax) { return false ; } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { return false ; } // Intersection. output->fraction = tmin; output->normal = normal; return true ; }
- Box2D 射线和AABB的碰撞检测
- Box2D射线和AABB碰撞检测
- Unity 碰撞检测和射线
- cocos2d AABB碰撞检测
- AABB外接盒碰撞检测
- 射线使用-碰撞检测
- 射线使用-碰撞检测
- Unity 碰撞检测、射线
- unity3D 射线碰撞检测
- Unity 射线检测碰撞
- Unity3d·射线·射线检测碰撞
- unity之飞机大战和碰撞检测、射线
- U3D Ray射线的创建和碰撞检测
- [Unity]Ray射线物理检测碰撞和LayerMask的使用
- 射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)
- Ray创建射线,碰撞检测
- Unity3D检测(碰撞、射线)
- Unity3D检测(碰撞、射线)
- Android 5.1 Audio HAL分析
- 【蓝桥杯】海盗喝酒
- Codeforces 645C Enduring Exodus 【二分】
- (4)Python读写csv文件
- PAT 乙级 1011.A+B和C
- Box2D射线和AABB碰撞检测
- 【蓝桥杯】返回把串s中第一个出现的数字的值
- 个人所得税计算器
- (5)POI读取Excel内容
- 点击textfield不弹出软键盘
- Ubuntu ulimit 系统最大打开文件个数 设置
- redis List链表结构
- 【蓝桥杯】扑克牌移动
- JS和Jquery操作label标签