`
jgsj
  • 浏览: 961304 次
文章分类
社区版块
存档分类
最新评论

C++求点和平面的关系

 
阅读更多

一个平面通常是由一个平面法线向量,如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 plane
Plane::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;
}


运行结果:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics