C++求点和平面的关系

来源:互联网 发布:windows 路由表 命令 编辑:程序博客网 时间:2024/04/29 15:07

一个平面通常是由一个平面法线向量,如v1(1,2,3),和点到原点(0,0,0)到平面的距离确定的。

当然数学中还有其他定义方法,但是DirectX和OpenGL都是使用这种定义方法的。这样定义的平面叫一般平面,其实是由点法式平面变形来的。

点我们可以使用Vector3类来确定,这个类既可以确定点,也可以确定向量。

Vector3这个类定义:http://blog.csdn.net/kenden23/article/details/16901331

下面定义一个平面:

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);float distance(float x, float y, float z);float distance(Vector3 v);PLAN_STATES classifyPoint(float x, float y, float z, float &dist);};


CreatePlane函数是用三个点确定一个平面,并计算成一般平面,存储好。 classfyPoint这个函数就是用来计算点和平面的关系的。

实现代码:

void Plane::createPlane(Vector3 v1, Vector3 v2, Vector3 v3){Vector3 t1, t2, n;t1 = v2 - v1;t2 = v3 - v1;n = t1.crossProduct(t2);n.normalize();a = n.x;b = n.y;c = n.z;d = -(a*v1.x + b*v1.y + c*v1.z);}float Plane::distance(float x, float y, float z){return a*x+b*y+c*z+d;}float Plane::distance(Vector3 v){return a*v.x+b*v.y+c*v.z+d;}//Claaisyf a point's position about the planePlane::PLAN_STATES Plane::classifyPoint(float x, float y, float z, float &dist){dist = distance(x,y,z);if (dist > uZero){return PLANT_FRONT;}if (dist < -uZero){return PLANT_BACK;}return PLANT_ON_PLANE;}


以平面的法向量为标准,如果在法向量正方向,那么就是在平面前面,如果在法向量反方向就是在平面后面,在Vector3文件中定义了个uZero = 1e-6 (=0.000001);如果距离少于uZero,那么就是在平面上。因为浮点数是有误差的,所以最好不用0作为比较。

测试代码:

#include<iostream>#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<<"v4's relationship with plane is: ";float dist = 0;switch (p1.classifyPoint(v4.x, v4.y, v4.z, dist)){case Plane::PLANT_BACK:cout<<"on the back of the plane.\n";break;case Plane::PLANT_FRONT:cout<<"on the front of the plane.\n";break;case Plane::PLANT_ON_PLANE:cout<<"right on the plane\n";break;default:break;}cout<<"v4 to plane's distance is: "<<dist<<endl;system("pause"); return 0;}


运行结果: