Я работаю в 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 = B-A // any non zero vector inside plane
X = X / |X| // unit in size
Y = C-A // any non zero vector inside plane
(X.Y) != 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>
поверхностные расстояния формы А в X,Y
направления. Это может пригодиться иногда. Если вам нужно вычислить u,v
от P
затем используйте скалярное произведение:
u = ((P-A).X) = dot(P-A,X)
v = ((P-A).Y) = dot(P-A,Y)
Который также может быть использован для преобразования в 2D вместо использования матрицы …
Других решений пока нет …