Уравнение плоскости. Расстояние от точки до плоскости


struct plane {

	float a,b,c,d;

};
struct point {

	float x,y,z;
};

int main (void)
{
	
	plane p = { 1.0, 0.0, 0.0, -20.0 };
	point v = { 25.0, 0.0, 0.0 };

	float distance = p.a * v.x + p.b * v.y + p.c * v.z + p.d; //distance = 5

	return 0;

}

Правило. Если нормаль плоскости смотрит в сторону начала координат, то дистанция до плоскости пложительная, иначе дистанция до плоскости отрицательная.

Пусть у нас есть плоскость, нормаль направлена вдоль положительного направления оси X, плосокость расположена на 20 единиц по оси X в положительном направлении, это значит начало координат с обратной стороны плоскости, за плоскостью, дистанция отрицательное значение -20. Если бы нормаль была направлена в строну начала координат, то дистанция в этом случае была бы положительной - значение 20 единиц.

Пусть у нас есть точка- точка лежит по оси X на расстоянии 25 единиц от начала координат.

Вполне логично- расстояние от точки до плоскости 5 единиц, что подтверждаеться формулой.


float distance = 1.0 * 25.0 + 0 * 0 + 0 * 0 + (-20.0) = 25.0 - 20.0 = 5.0;

Пусть у нас есть нормаль n и вектор v, и плоскость проходит через центр координатной системы, тогда дистанция до плоскости 0, а следующая формула покажет расстояние от точки v до плоскости:


float distance = n.x * v.x + n.y * v.y + n.z * v.z;

Формулу определения расстояния от точки до полоскости можно использовать в тех случаях когда нужно определить- точка расположена перед плоскостью, или за плоскостью. В нашем случае расстояние от точки до полоскости положительное число 5 единиц, то есть точка расположена перед плосокстью. Если бы дистанция была отрицательной- это значит что точка расположена с обратной стороны плоскости. Если дистанция равна 0 то точка лежит на плоскости. Обратная сторона плоскости это та которая расположена в обратном направлении нормали к плоскости. То есть нормаль показывает в одну сторону, а обратная сторона плоскости (отрицательная дистацния) с другой стороны.

Если мы хотим поменять знак дистацнию плоскости от начала координат мы должны инвертировать ее нормаль, то есть нормаль умножить на -1. Например эти две плоскости p1 и p2 аналогичны, расположены на 20 единиц от начала координат, отличаються только направлением нормали. Эти две плоскости лежат в одной плоскости.


plane p1 = { 1.0, 0.0, 0.0, -20.0 };
plane p2 = { -1.0, 0.0, 0.0, 20.0 };

Следует раличать такие понятия как- расстояние плоскости от начала координат, расстояние точки от плоскости, и расстояние точки от начала координат.

Уравнение плоскости: Ax + By + Cz + D = 0

Любая точка пространства либо принадлежит плоскости, либо «спереди» от плоскости, либо «за» плоскостью. Плоскость определяется четырьмя числами: A,B,C и D, где {A,B,C} – вектор нормали к этой плоскости, а D – расстояние до начала координат. Что бы понять находится ли точка перед плоскостью или нет надо вычислить расстояние от точки плоскости. Если расстояние положительно, значит, точка лежит перед плоскостью, отрицательна – значит за плоскостью. Вот формула для вычисления расстояния точки до плоскости:


distance = A * X + B * Y + C * Z + D

Где A, B, C, и D - четыре числа, которые определяют плоскость и X, Y, и Z - координаты точки.

Предположим мы извлекли 6 плоскостей области просмотра из матриц World, View, Projection.


float frustum[6][4];

Теперь мы можем написать функцию для проверки - видима точка или нет.

	
bool PointInFrustum( float x, float y, float z )

{
   int p;

   for( p = 0; p < 6; p++ )

      if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 )

         return false;

   return true;

}

bool PolygonInFrustum( int numpoints, vertex* pointlist )
{
	int f, p;

	for( f = 0; f < 6; f++ )
	{
		for( p = 0; p < numpoints; p++ )
		{
			if( frustum[f][0] * pointlist[p].x + frustum[f][1] * pointlist[p].y + frustum[f][2] * pointlist[p].z + frustum[f][3] > 0 )
            		break;
		}
	
		if( p == numpoints )
			return false;
   }

   return true;
}