У меня есть треугольник с точками A, B, C и точкой в пространстве (P). Как я могу получить расстояние от точки до плоскости? Мне нужно вычислить расстояние от P до плоскости, даже если мой треугольник лежит далеко (или не выше точки, как на картинке).
Точка и треугольник: 





Если точка P(x1,y1,z1) и самолет ax+by+cz+d = 0
dist = Abs(a*x1+b*y1+c*z1+d) / Sqrt(a^2+b^2+c^2)
@MBo да, это больше похоже на отзыв отрицательного голоса ... кстати, первый подход в ссылке - это то, о чем мой ответ
Формула @Spektre с базовой точкой не включает d, без нее - включает (d добавлено мной несколько часов назад)
@MBo хех, должно быть, где-то закэширован, теперь я вижу это в истории редактирования, но всего несколько минут назад не в самом ответе ...
Преобразовал его в код:
var a = pos1.y * (pos2.z - pos3.z) + pos2.y * (pos3.z - pos1.z) + pos3.y * (pos1.z - pos2.z);
var b = pos1.z * (pos2.x - pos3.x) + pos2.z * (pos3.x - pos1.x) + pos3.z * (pos1.x - pos2.x);
var c = pos1.x * (pos2.y - pos3.y) + pos2.x * (pos3.y - pos1.y) + pos3.x * (pos1.y - pos2.y);
var d = -(pos1.x * (pos2.y * pos3.z - pos3.y * pos2.z) +
pos2.x * (pos3.y * pos1.z - pos1.y * pos3.z) +
pos3.x * (pos1.y * pos2.z - pos2.y * pos1.z));
var dist = Math.Abs(a * point.x + b * point.y + c * point.z + d) / Math.Sqrt(a * a + b * b + c * c);
Оно работает! Спасибо!
Я предполагаю, что вы хотите вычислить перпендикулярное расстояние между точкой и плоскостью, учитывая 3 точки на ней, образующие треугольник. Здесь векторный математический подход:
определения
пусть точки треугольника будут p0,p1,p2, а проверенная точка p.
нормальная плоскость
сначала нам нужно получить нормаль к плоскости, то есть простое векторное умножение любых двух непараллельных и ненулевых векторов внутри плоскости:
n = cross( p1-p0 , p2-p0 )
и нормализуйте его к единичному вектору (для упрощения):
n = n/|n|
перпендикулярное расстояние
мы можем использовать скалярное произведение для этого, поэтому просто создайте вектор, идущий из любой точки плоскости в вашу проверенную точку, и расставьте точки с единичной нормалью...
dist = |dot ( p-p0 , n )|
последнее абсолютное значение (на скалярном расстоянии) просто избавится от знака результата, который говорит вам, находится ли точка p в направлении нормали n или в противоположном направлении, иногда требуется такая информация, поэтому в таком случае удалите самое внешнее значение абс и использовать полигональную обмотку и операнды перекрестного произведения, чтобы сохранить желаемое нормальное направление.
Здесь (ищите [править2]) вы найдете уравнения cross , dot и ||, используемые при необходимости:
поэтому, если я соберу все вместе в виде кода:
U.x=p1.x-p0.x; V.x=p2.x-p0.x; // basis vectors on the plane
U.y=p1.y-p0.y; V.y=p2.y-p0.y;
U.z=p1.z-p0.z; V.z=p2.z-p0.z;
n.x=(U.y*V.z)-(U.z*V.y); // plane normal
n.y=(U.z*V.x)-(U.x*V.z);
n.z=(U.x*V.y)-(U.y*V.x);
dist = sqrt( (n.x*n.x) + (n.y*n.y) + (n.z*n.z) ); // normalized
n.x /= dist;
n.y /= dist;
n.z /= dist;
dist = abs( (p.x-p0.x)*n.x + (p.y-p0.y)*n.y + (p.z-p0.z)*n.z ); // your perpendicular distance
Это действительно тщательный ответ. Престижность. Но я бы оставил знак dist. Это полезно.
Просто точность, в последнем ответе есть двойной обмен знаками. В var d нет - и для доступа к расстоянию нужно вычислить:
var dist = Math.Abs(a * point.x + b * point.y + c * point.z - d) / Math.Sqrt(a * a + b * b + c * c);
Ничего не меняет на выходе, но если вы впоследствии используете уравнение плоскости, это важно
Вы имеете в виду расстояние до опорной плоскости или кратчайшее расстояние до точек треугольника?