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