射線和軸對齊包圍盒相交檢測-簡潔算法(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 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章