最近在看計算機圖形學的一些基本的算法,看到射線和軸對齊包圍盒的相交問題.
這其實是一個簡單的常用的算法,網上也有很多帖子解釋,但是用到的方法都是類似 “厚板方法”。
大概是這樣:
或者這樣:
不知道爲啥,我總很難理解這種方法。
自己常用的算法是分離軸算法,當然上面的算法也用到了分離軸定理,這個算法實在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 intersected
template<class T>
static bool RayWithAABB(DRay<T > &ray,DBox<T> &box){
///origin point of ray
DPoint<T > mOrigin = ray.GetSourcePoint();
/// direction of ray
DDirection<T> mDir = ray.Direction();
/// make abs of direction
DDirection<T> mFDir =
DDirection<T>(std::abs(mDir.x()), std::abs(mDir.y()), std::abs(mDir.z()));
///box center and extent
DPoint<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