判断平面和AABB包围体是否发生碰撞

  • Post author:
  • Post category:其他


首先在平面类中增加两个函数Intersect,如下:

class Plane
{
public:
	float a, b, c, d;
	enum PLAN_STATES
	{
		PLANT_FRONT,
		PLANT_BACK,
		PLANT_ON_PLANE
	};

	Plane():a(0), b(0), c(0), d(0){}
	Plane(float a1, float b1, float c1, float d1):a(a1), b(b1), c(c1), d(d1){}

	void createPlane(Vector3 v1, Vector3 v2, Vector3 v3);
	bool intersect(const Vector3 &bbMin, const Vector3 &bbMax);
	bool intersect(const Vector3 &pos, float radius);
	float distance(float x, float y, float z);
	float distance(Vector3 v);
	PLAN_STATES classifyPoint(float x, float y, float z, float &dist);
};


AABB通常是由最小值和最大值组成的,这里就用const Vector3 &bbMin和const Vector3 &bbMax表示一个AABB包围体。

这里通过判断平面的法向量的方向,确定离平面最近的点为最小点min,离平面最远的为max。

通过判断三个情况:

1 最小点min在平面正面,那么肯定为不相交了。

2 最小点min在平面负面,最大点max在正面,那么就相交了。

3 如果最大点在平面负面,那么就不相交。

同时也带了Shpere(圆形)包围体和平面相交的函数,那更容易。

//Calculate the AABB intersect the plane or not.
bool Plane::intersect(const Vector3 &bbMin, const Vector3 &bbMax)
{
	Vector3 min, max;
	Vector3 normal(a,b,c);
	if (normal.x >= 0.0f)
	{
		min.x = bbMin.x;
		max.x = bbMax.x;
	}
	else
	{
		min.x = bbMax.x;
		max.x = bbMin.x;
	}
	if (normal.y >= 0.0f)
	{
		min.y = bbMin.y;
		max.y = bbMax.y;
	}
	else
	{
		min.y = bbMax.y;
		max.y = bbMin.y;
	}
	if (normal.z >= 0.0f)
	{
		min.z = bbMin.z;
		max.z = bbMax.z;
	}
	if (distance(min) > 0.0f)
	{
		return false;
	}
	if (distance(max) >= 0.0f)
	{
		return true;
	}
	return false;
}

//Calculate the sphere bounding volume intersect the plane or not.
bool Plane::intersect(const Vector3 &pos, float radius)
{
	float dp = fabsf(distance(pos));
	if(dp <= radius)
		return true;
	return false;
}


测试:

#include<iostream>
#include<vector>
#include<string>
#include"Plane.h"

using namespace std;

int main() 
{
	Plane p1;
	Vector3 v1(1.0f, 0.0f, 0.0f);
	Vector3 v2(0.0f, 1.0f, 0.0f);
	Vector3 v3(0.0f, 0.0f, 1.0f);
	p1.createPlane(v1, v2, v3);
	cout<<"We have create a plane:\n";
	cout<<"Plane's a = "<<p1.a<<endl;
	cout<<"Plane's b = "<<p1.b<<endl;
	cout<<"Plane's c = "<<p1.c<<endl;
	cout<<"Plane's d = "<<p1.d<<endl;
	cout<<"v1 to Plane's distance is: "<<p1.distance(v1)<<endl;

	Vector3 v4(8.0f, 8.0f, 8.0f);
	cout<<"Vector3 v4 is: ";
	v4.printVec3();
	
	cout<<"Intersect with AABB test: "<<endl;
	if(p1.intersect(v1+11,v4)) cout<<"Yes, intersect.\n";
	else cout<<"Not intersect.\n";
	
	cout<<"Intersect with sphere test: "<<endl;
	if(p1.intersect(v4,15.0f)) cout<<"Yes, intersect.\n";
	else cout<<"Not intersect.\n";

	system("pause");
	return 0;
}

运行: