射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)

时间:2021-12-13 05:19:23

最近在看计算机图形学的一些基本的算法,看到射线和轴对齐包围盒的相交问题.

这其实是一个简单的常用的算法,网上也有很多帖子解释,但是用到的方法都是类似 “厚板方法”。

大概是这样:

射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)

或者这样:

射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)

射线和轴对齐包围盒相交检测-简洁算法(ray-aabb overlap test alogrithm)

不知道为啥,我总很难理解这种方法。

自己常用的算法是分离轴算法,当然上面的算法也用到了分离轴定理,这个算法实在OPCODE中看到的,贴出来和大家共享,感觉这个算法还是比较

简单明了的:

 
/// @brief test if ray and aabb box is intersected////// @param ray DRay  of type T/// @param box DBox  of type T./// @return a bool value that whether ray and aabb is intersectedtemplate<class T>static bool RayWithAABB(DRay<T > &ray,DBox<T> &box){///origin point of rayDPoint<T > mOrigin = ray.GetSourcePoint();/// direction of rayDDirection<T> mDir = ray.Direction();/// make abs of directionDDirection<T> mFDir = DDirection<T>(std::abs(mDir.x()), std::abs(mDir.y()), std::abs(mDir.z()));///box center and extentDPoint<T > center  = box.GetCenter();DPoint<T > extents = box.GetExtents();T Dx = mOrigin.x() - center.x();if (std::abs(Dx) > extents.x() && Dx*mDir.x() >= static_cast<T>(0))return false;T Dy = mOrigin.y() - center.y();if (std::abs(Dy) > extents.y() && Dy*mDir.y() >= static_cast<T>(0))return false;T Dz = mOrigin.z() - center.z();if (std::abs(Dz) > extents.z() && Dz*mDir.z() >= static_cast<T>(0))return false;T f;f = mDir.y() * Dz - mDir.z() * Dy;if (std::abs(f) > extents.y()*mFDir.z() + extents.z()*mFDir.y())return false;f = mDir.z() * Dx - mDir.x() * Dz;if (std::abs(f) > extents.x()*mFDir.z() + extents.z()*mFDir.x())return false;f = mDir.x() * Dy - mDir.y() * Dx;if (std::abs(f) > extents.x()*mFDir.y() + extents.y()*mFDir.x())return false;return true;}

参考:

http://www.codercorner.com/Opcode.htm

https://github.com/DamonsJ/DamonsGraphic

http://blog.csdn.net/i_dovelemon/article/details/38342739

https://en.wikipedia.org/wiki/Hyperplane_separation_theorem