欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-13 13:48:10
...

首先在平面类中增加两个函数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;
}

运行:


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