厚光线与AABB的相互作用

我想用一个AABB与厚光线(实际上是一个圆柱)相交。 当前执行射线交叉的代码如下。

template <class RealT> bool CAABB<RealT>::Pick(const CPoint3T & base, const CVector3T & dir) const { // SLAB based optimized ray/AABB intersection routine // Idea taken from http://ompf.org/ray/ RealT l1 = (_minPnt.x - base.x) / dir.x; RealT l2 = (_maxPnt.x - base.x) / dir.x; RealT lmin = minT( l1, l2 ); RealT lmax = maxT( l1, l2 ); l1 = (_minPnt.y - base.y) / dir.y; l2 = (_maxPnt.y - base.y) / dir.y; lmin = maxT( minT( l1, l2 ), lmin ); lmax = minT( maxT( l1, l2 ), lmax ); l1 = (_minPnt.z - base.z) / dir.z; l2 = (_maxPnt.z - base.z) / dir.z; lmin = maxT( minT( l1, l2 ), lmin ); lmax = minT( maxT( l1, l2 ), lmax ); if( (lmax >= 0.0f) & (lmax >= lmin) ) { // Consider length const CVector3T rayDest = base + dir; CPoint3T rayMins( minT( rayDest.x, base.x), minT( rayDest.y, base.y ), minT( rayDest.z, base.z ) ); CPoint3T rayMaxs( maxT( rayDest.x, base.x), maxT( rayDest.y, base.y ), maxT( rayDest.z, base.z ) ); return (rayMins.x < _maxPnt.x) && (rayMaxs.x > _minPnt.x) && (rayMins.y < _maxPnt.y) && (rayMaxs.y > _minPnt.y) && (rayMins.z < _maxPnt.z) && (rayMaxs.z > _minPnt.z); } else return false; } 

我想写一个例程,为ray_thickness(圆柱体的直径)添加一个额外的参数并计算交点。

我看到2个天真的方法,我不知道哪一个更快:

  1. 您可以将AABB投影到与光线方向正交的平面上,然后解决二维球体与投影AABB相交的问题。

  2. 你可以在每一个3轴上投影你的圆柱体,并检查与2D矩形(这是AABB的投影)的交集,然后结合3个结果来决定3D交集。

我认为你会发现,做几次射线检查比检查几个相互对立的stream形会更快,更简单。 他们把这些射线包称为光线追踪文献。

我建议使用6光线的圆柱半径,一个为中心,总共7。你甚至可以逃脱less至4或5射线,取决于你想如何近似的圆柱体形状。 这对于非轴alignment的对象来说是快速的,对于AABB可以是快速的。 如果包内的每个射线之间的距离足够小(比最小的可检测实体的直径略小),那么您绝不会错过任何东西。 这里是一个7射线圆柱体的图片:

  o oo o oo o 

我甚至可以说,由于成本的原因,这是游戏中比较常见的方法。