Я работаю в php с 3D-геометриями (не лучшим выбором, я знаю …). У меня есть копланарные трехмерные точки K, также с x, y, z. Вместе они образуют многоугольник. Мне нужно триангулировать этот многоугольник. У меня уже есть рабочая функция трауляции, которая работает для 2D-полигонов. Поэтому я хочу повернуть заданные точки так, чтобы они лежали на плоскости, параллельной плоскости x, y. После этого я могу триангулировать его, используя значения x, y. Следующий псевдокод должен описать, как я хочу достичь этой цели.
Я создаю следующий код со ссылкой на это (я использую ответ, принятый из OP): https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector -a-to-vector-b-in-3d , но он не работает, как я ожидал. Чтобы узнать, работает ли это, каждая отображаемая точка должна иметь одно и то же значение «z». Вот вопрос, как мне получить правильную матрицу вращения? Или я сделал концептуальную ошибку?
function matrixRotationMapping(Point $p, Point $q, Point $r) { $normalPolygon =calculatePlaneNormal($p, $q, $r); $v = crossProduct($normalPolygon, new Point(0, 0, 1)); $c = dotProduct($normalPolygon, new Point(0, 0, 1)); $matrix = buildRotationMatrix($v, $c); return $matrix; } function buildRotationMatrix($v, $c) { $R2 = new Matrix(array(array(1, -$v->z, $v->y), array($v->z, 1, -$v->x), array(-$v->y, $v->x, 1))); $costant = 1/(1+$c); $R3 = multiplyMatrices($R2, $R2); $R3 = multiplyMatricesWithFactor($R3, $costant); $finalMatrix = sumMatrices($R2, $R3); return $finalMatrix; } function calc2DMapping($points) { $rotationMatrix = matrixRotationMapping($points[0], $points[1], $points[2]); foreach($points as $point) { $mappedPoint = $rotationMatrix->multiplyWithPoint($point); $mappedPoints[] = new MappedPoint($mappedPoint); } }
Я нашел другое полезное описание проблемы, но я не смог ее реализовать: Отображение координат из плоскости, заданной нормальным вектором в плоскость XY
Заранее благодарим за внимание.
Сначала вам нужны базовые векторы X,Y,Z
Поэтому сначала возьмите среднюю точку A
и две удаленные точки B,C
(не в одной строке) из вашего набора данных. X,Y
должны лежать в плоскости, а Z
должен быть нормален к ней, поэтому:
X = BA // any non zero vector inside plane X = X / |X| // unit in size Y = CA // any non zero vector inside plane (XY) != 0 // but not parallel to X !!! Y = Y / |Y| // unit in size
Вычислите нормаль к плоскости, в которой находятся ваши точки, и исправьте ось Y.
Z = X x Y // cross product gives you perpendicular vector Y = Z x X // now all vectors are perpendicular and unit
Итак, подайте эти 3 вектора в поворотную часть вашей матрицы преобразования и установите начало в A
Но поскольку вам нужно перейти от вашего набора данных к локальной координате плоскости, вам нужна обратная матрица (или использовать псевдоинверсию на основе транспонирования)
В любом случае теперь с базовыми векторами вы можете параметрически отобразить свою плоскость следующим образом:
P(u,v) = A + u*X + v*Y
Где u,v = <-inf,+inf>
– поверхностные расстояния, формы A в направлениях X,Y
Иногда это может пригодиться. Если вам нужно вычислить u,v
из P
то используйте dot-продукт:
u = ((PA).X) = dot(PA,X) v = ((PA).Y) = dot(PA,Y)
Что также можно использовать для преобразования в 2D вместо использования матрицы …