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