ПРЕДУПРЕЖДЕНИЕ - Почти все, что я знаю об использовании барицентрических координат и использовании матриц для решения линейных уравнений, было изучено вчера вечером, потому что я нашел этот вопрос настолько интересным.Таким образом, следующее может быть неправильным, неправильным, неправильным - , но некоторые введенные мной тестовые значения, похоже, работают .Парни и девушки, пожалуйста, не стесняйтесь разорвать это на части, если я облажался полностью - но здесь все.
Поиск барицентрических координат в трехмерном пространстве (с небольшой помощью из Википедии)
Дано:
v0 = (x0, y0, z0)
v1 = (x1, y1, z1)
v2 = (x2, y2, z2)
p = (xp, yp, zp)
Найти барицентрические координаты: b0, b1, b2 точки p относительно треугольника, определенного v0, v1 и v2
Зная, что:
xp = b0*x0 + b1*x1 + b2*x2
yp = b0*y0 + b1*y1 + b2*y2
zp = b0*z0 + b1*z1 + b2*z2
Который может быть записан как
[xp] [x0] [x1] [x2]
[yp] = b0*[y0] + b1*[y1] + b2*[y2]
[zp] [z0] [z1] [z2]
или
[xp] [x0 x1 x2] [b0]
[yp] = [y0 y1 y2] . [b1]
[zp] [z0 z1 z2] [b2]
, переставленный как
-1
[b0] [x0 x1 x2] [xp]
[b1] = [y0 y1 y2] . [yp]
[b2] [z0 z1 z2] [zp]
, определяющим фактором матрицы 3x3 является:
det = x0(y1*z2 - y2*z1) + x1(y2*z0 - z2*y0) + x2(y0*z1 - y1*z0)
его присоединение равно
[y1*z2-y2*z1 x2*z1-x1*z2 x1*y2-x2*y1]
[y2*z0-y0*z2 x0*z2-x2*z0 x2*y0-x0*y2]
[y0*z1-y1*z0 x1*z0-x0*z1 x0*y1-x1*y0]
, давая:
[b0] [y1*z2-y2*z1 x2*z1-x1*z2 x1*y2-x2*y1] [xp]
[b1] = ( [y2*z0-y0*z2 x0*z2-x2*z0 x2*y0-x0*y2] . [yp] ) / det
[b2] [y0*z1-y1*z0 x1*z0-x0*z1 x0*y1-x1*y0] [zp]
Если вам нужно проверить количество точек на треугольнике, остановитесь здесь.Вычислите вышеупомянутую матрицу 3x3 один раз для треугольника (также разделив ее на определитель), а затем поставьте точечное произведение, которое получается в каждой точке, чтобы получить барицентрические координаты для каждой точки.
Если вы делаете это только один раздля каждого треугольника приведено умноженное выше (любезно предоставлено Maxima):
b0 = ((x1*y2-x2*y1)*zp+xp*(y1*z2-y2*z1)+yp*(x2*z1-x1*z2)) / det
b1 = ((x2*y0-x0*y2)*zp+xp*(y2*z0-y0*z2)+yp*(x0*z2-x2*z0)) / det
b2 = ((x0*y1-x1*y0)*zp+xp*(y0*z1-y1*z0)+yp*(x1*z0-x0*z1)) / det
Это довольно много сложений, вычитаний и умножений - три деления - но без функций sqrts или trig.Очевидно, это займет больше времени, чем чистые 2D-кальки, но в зависимости от сложности эвристики проекции и кальков, это может оказаться самым быстрым маршрутом.
Как я уже упоминал - я понятия не имею, что яговорить о - но, возможно, это сработает, или, может быть, кто-то другой может прийти и исправить это.