разобрался (это автор вопроса).Это была просто опечатка, я не рассчитал нормальную плоскость в правильном направлении ... Я не сказал, что это было (v0 X v1), это было случайно (v1 X v0).Вы можете увидеть это в коде.Так что, если самолет направлен в другую сторону, вы не можете проецировать на него.
Потому что это глупая ошибка.Для всех, кто хочет узнать математику этой матричной проекции на плоскость, я попытаюсь объяснить это:
Прежде чем начать, я предполагаю немного грубое знание линейной алгебры.Не нужно много.
Скажем, у нас есть плоскость с нормальным N с точкой Q на ней.Для каждой точки P (P-Q).N=0
(это точечное произведение), если (и только если) P находится на плоскости, поскольку векторы (P-Q)
и N перпендикулярны.
Теперь давайте предположим, что у нас также есть(фиксированный точечный источник света) точка S. Мы хотели бы проецировать точку P на нашу плоскость из этого точечного источника света.Это означает, что мы хотели бы найти точку R, которая находится где-то на прямой, определенной точками P и S, и это также на плоскости.Другими словами, найдите скаляр t, такой что S+t(P-S)=R
, такой, что R находится на плоскости.(P-S)
- это вектор направления от точечного источника света через точку P. Мы "проходим" по этому вектору определенную величину t, начиная с точки S, пока не приземлимся на плоскости.
От 2 параграфов назадмы узнали хороший трюк, чтобы узнать, находится ли точка на плоскости или нет.Поэтому, если мы применим это к R, мы получим, что R находится на плоскости, если (и только если):
N.(R-Q)=0
N.R-N.Q=0
N.R=N.Q
N.(S+t(P-S))=N.Q
N.S+tN.(P-S)=N.Q
t=(N.Q-N.S)/(N.(P-S))
Теперь, если мы вернем это в определение R:
R=S+(N.Q-N.S)*(1/(N.(P-S))*(P-S)
Давайте определим N.(P-S)
как k
kR=(N.(P-S))*S+(N.Q-N.S)*P-(N.Q-N.S)*S
kR=(N.P)*S+(N.Q-N.S)*P-(N.Q-N.S)*S-(N.S)*S
kR=(N.P)*S+(N.Q-N.S)*P-(N.Q)*S
Давайте напомним себе, что мы знаем, что мы не знаем, и что мы хотим знать.Мы знаем, что N и Q и S. P дан нам, и мы хотели бы найти R. Другими словами, мы хотели бы выразить R для P, используя N, Q и S. Давайте продолжим разбираться с этим немногодалее,
kR=(N_x*P_x+N_y*P_y+N_z*P_z)*S+(N.Q-N.S)*P-(N.Q)*S
R - точка, поэтому давайте определим каждую из ее координат, с координатами P (а также S, потому что у нас он также находится в правой части уравнения).
kR_x=[N_x*S_x+(N.Q-N.S)]P_x+[N_y*S_x]P_y+[N_z*S_x]P_z-(N.Q)*S_x
kR_y=[N_x*S_y]P_x+[N_y*S_y+(N.Q-N.S)]P_y+[N_z*S_y]P_z-(N.Q)*S_y
kR_z=[N_x*S_z]P_x+[N_y*S_z]P_y+[N_z*S_z+(N.Q-N.S))]P_z-(N.Q)*S_z
Может показаться, что мы ничего не получили, так как мы получили это k на левой стороне, и нам все еще нужно делить на него (и это k определяется P, тем не менее!).Не беспокойтесь, потому что OpenGL использует четыре элемента, а не три.Этот последний четвертый элемент используется для матриц перевода и интерполяции глубины перспективы.Для наших нужд сейчас все, что мы должны знать, это то, что openGL делит координаты каждой вершины на четвертый элемент.Это означает, что эта страшная k - наш четвертый элемент.мы получаем:
R_w=k
R_w=N.(P-S)
R_w=N.P-N.S
R_w=[N_x]P_x+[N_y]P_y+[N_z]P_z-N.S
Хорошо, мы определили наши R через P, используя N, S и Q. Давайте поместим это в матрицу M. Мы хотим:
M * P = R
Итак,
M=
N_x*S_x + (N.Q-N.S), N_y*S_x, N_z*S_x, -(N.Q)*S_x
N_x*S_y, N_y*S_y + (N.Q-N.S), N_z*S_y, -(N.Q)*S_y
N_x*S_z, N_y*S_z, N_z*S_z + (N.Q-N.S), -(N.Q)*S_z
N_x, N_y, N_z, -(N.S)
Помня об этом, помните, что, поскольку P - точка, четвертый элемент равен 1. (! = 0, если быть точным, но мы можем предположить, что это устройствонормализованная вершина)
Об уравнении плоскости.Уравнение плоскости - это вектор, в котором первые три элемента имеют нормаль.И его четвертый элемент - это расстояние от начала координат со знаком.Другой способ вычислить расстояние от плоскости до начала координат:
При заданной точке Q на плоскости с нормальным N расстояние плоскости от начала координат составляет | NQ |
Довольно просто,право?Это верно, поскольку:
N.Q=|N|*|Q|*cos(N,Q)
и |N|=1
, что дает нам:
N.Q=|Q|*cos(N,Q)=|Q|*d/|Q|=d
где d - расстояние до плоскости от начала координат.Или это размер вектора N;и величина N - это величина расстояния до плоскости от начала координат.Это можно увидеть, нарисовав плоскость, выбрав некоторую точку Q на плоскости, нарисовав нормаль N, идущую к плоскости из начала координат, и посмотрев на треугольник, образованный линиями двух векторов и плоскости.
В приведенной выше матрице замените -N.Q на d (последний элемент в уравнении плоскости), и все готово. (д = -N.Q). Эта матрица, заданная точкой P, будет проецировать ее на плоскость, определяемую N и Q, из светового пятна, определяемого S.
Надеюсь, что научит вас чему-то новому. Если я допустил ошибку, прокомментируйте, и я исправлю это.