OBB方向包围盒碰撞检测算法(原理与代码)

原理:OBB间的相交测试基于分离轴理论(separating axis theory)。若两个OBB在一条轴线上(不一定是坐标轴)上的投影不重叠,则这条轴称为分离轴。若一对OBB间存在一条分离轴,则可以判定这两个OBB不相交。对任何两个不相交的凸三维多面体,其分离轴要么垂直于任何一个多面体的某一个面,要么同时垂直于每个多面体的某一条边。因此,对一对OBB,只需测试15条可能是分离轴的轴(每个OBB的3个面方向再加上每个OBB的3个边方面的两两组合),只要找到一条这样的分离轴,就可以判定这两个OBB是不相交的,如果这15条轴都不能将这两个OBB分离,则它们是相交的。 

 

代码:

FBox,FOrientedBox都是UE4数据结构
/**@前路漫漫 oriented box intersection */
bool IntersectOOBB(const FOrientedBox& OB1, const FOrientedBox& OB2)
{
	const int32 ObVertNum = 8;
	FVector OB1Vert[ObVertNum] = { FVector::ZeroVector };
	OB1.CalcVertices(OB1Vert);

	FVector OB2Vert[ObVertNum] = { FVector::ZeroVector };
	OB2.CalcVertices(OB2Vert);

	//calculate 1d bound box
	auto affectMinMaxValue = [](float& min, float& max, float value)
	{
		min = std::min(min, value);
		max = std::max(max, value);
	};

	//determin whether two obb(box1, box2) exit a separate axis on a given axis(axe)
	auto isSATFoundedOnAxe = [&affectMinMaxValue, &OB1Vert, &OB2Vert, &ObVertNum](const FOrientedBox& box1, const FOrientedBox& box2, const FVector& axe)->bool
	{
		float minBox1 = std::numeric_limits<float>::max(), maxBox1 = std::numeric_limits<float>::min(), minBox2 = std::numeric_limits<float>::max(), maxBox2 = std::numeric_limits<float>::min();

		for (int32 i = 0; i < ObVertNum; i++)
		{
			affectMinMaxValue(minBox1, maxBox1, axe | OB1Vert[i]);
		}

		for (int32 i = 0; i < ObVertNum; i++)
		{
			affectMinMaxValue(minBox2, maxBox2, axe | OB2Vert[i]);
		}

		//try seg1 on seg2 or seg2 on seg1
		return ((minBox2 <= maxBox1 && minBox2 >= minBox1) ||
			(maxBox2 <= maxBox1 && maxBox2 >= minBox1)) ||
			((minBox1 <= maxBox2 && minBox1 >= minBox2) ||
				(maxBox1 <= maxBox2 && maxBox1 >= minBox2));
	};

	/*Exclude the majority case of no collision*/
	FBox Box1AABB(OB1Vert, ObVertNum);
	FBox Box2AABB(OB2Vert, ObVertNum);
	if (!Box1AABB.Intersect(Box2AABB))
		return false;

	/*Use SAT to know if collision existe*/
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisX)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisY)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisZ)) return false;

	if (!isSATFoundedOnAxe(OB1, OB2, OB2.AxisX)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB2.AxisY)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB2.AxisZ)) return false;

	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisX ^ OB2.AxisX)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisX ^ OB2.AxisY)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisX ^ OB2.AxisZ)) return false;

	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisY ^ OB2.AxisX)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisY ^ OB2.AxisY)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisY ^ OB2.AxisZ)) return false;

	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisZ ^ OB2.AxisX)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisZ ^ OB2.AxisY)) return false;
	if (!isSATFoundedOnAxe(OB1, OB2, OB1.AxisZ ^ OB2.AxisZ)) return false;

	return true;
}

 

### 回答1: AABB包围盒是一个长方形盒子,其各个面都坐标轴平行。它通常用于快速确定物体是否另一个物体发生碰撞。 包围球是一个具有固定半径的球形对象,它通常用于包围一个物体或一组物体。包围球可以用于求取物体之间的距离或者相交情况。 方向包围盒OBB是一个最适合物体形状的盒子,它可以朝着任意方向旋转。OBB可以用于求取物体之间的碰撞或相交关系。 固定方向凸包FDH是一个凸多边形,它是根据点云构造出来的具有一定厚度的表面。FDH可以用于进行3D渲染或者物体刚体碰撞计算。 希望我的回答能够满足您的需求。如果您还有其他问题,请随时提出。 ### 回答2: AABB包围盒、包围球、方向包围盒OBB和固定方向凸包FDH是计算机图形学和碰撞检测中常用的表示物体边界的方法。 AABB包围盒(Axis-Aligned Bounding Box)是一种简单的包围盒形式,它是通过对象的最小和最大的x、y和z值定义的。AABB包围盒是一个坐标轴对齐的长方体。在碰撞检测中,通过比较两个AABB包围盒之间的位置关系,可以快速判断是否发生碰撞。 包围球是一个以物体中心为原点,半径为半径的球体。它可以更准确地逼近物体形状,但相对于AABB包围盒来说计算复杂度更高。包围球对于检测是否有物体其他物体相交很有用。 方向包围盒OBB(Oriented Bounding Box)是一种能够任意朝向的盒子。AABB包围盒不同,OBB是一个可以在3D空间中旋转的长方体。OBB可以更准确地逼近对象的形状,但相对于AABB包围盒来说计算复杂度更高。OBB广泛应用于碰撞检测和物体包围盒等领域。 固定方向凸包FDH(Fixed Direction Convex Hull)是一个定义了对象的最小凸多边形的包围体。它可以通过一系列的向量定义,并且具有固定的朝向。FDH通常用于包围多个物体或者给定一个3D场景的碰撞检测。 ### 回答3: AABB包围盒(Axis-Aligned Bounding Box)是一种包围物体的立方体框,其边坐标轴平行。这意味着包围盒的六个面总是世界坐标系的坐标轴对齐。AABB包围盒通常用于快速确定物体之间是否相交,以及进行碰撞检测。 包围球(Bounding Sphere)是一种包围物体的球体,其半径足够小以便覆盖了整个物体。包围球的中心点位于物体的重心处。包围球常用于确定物体之间的距离,例如在碰撞检测和视锥剔除(Frustum Culling)中使用。 方向包围盒OBB(Oriented Bounding Box)是一种包围物体的立方体框,物体的方向相关。AABB不同,OBB的边不必坐标轴平行,其方向可以被旋转调整以适应物体的朝向。OBB在一些模拟和碰撞检测算法中被广泛使用。 固定方向凸包FDH(Fixed-Orientation Convex Hull)是一种凸多边形,其边界能够完全包围物体。FDH通常在较早期的物理引擎中使用,用于对物体进行碰撞检测和坐标转换。通过简单的几何运算,FDH可以更高效地检测碰撞,并提供物体之间的最小接触区域。然而,FDH也有一些局限性,例如无法准确描述非凸物体的形状。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值