射线和轴对齐包围盒相交检测-简洁算法(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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值