Если у вас есть или вы можете легко вычислить вектор нормали к плоскости, в которой находятся ваши точки, я думаю, что самый простой способ сделать это - повернуть вокруг оси, общей для двух плоскостей. Вот как я могу это сделать:
- Пусть
M
- вектор нормали к вашей текущей плоскости, а N
- вектор нормали к плоскости, в которую вы хотите повернуть. Если M == N
, вы можете остановиться и оставить исходные точки без изменений.
Рассчитать угол поворота как
costheta = dot(M,N)/(norm(M)*norm(N))
Рассчитать ось вращения как
axis = unitcross(M, N)
где unitcross
- это функция, которая выполняет перекрестное произведение и нормализует его к единичному вектору, т.е. unitcross(a, b) = cross(a, b) / norm(cross(a, b))
. Как указано в комментарии user1318499 , этот шаг может вызвать ошибку, если M == N
, если ваша реализация unitcross
не возвращает (0,0,0)
, когда a == b
.
Вычислить матрицу вращения от оси и угла как
c = costheta
s = sqrt(1-c*c)
C = 1-c
rmat = matrix([ x*x*C+c x*y*C-z*s x*z*C+y*s ],
[ y*x*C+z*s y*y*C+c y*z*C-x*s ]
[ z*x*C-y*s z*y*C+x*s z*z*C+c ])
, где x
, y
и z
являются компонентами axis
. Эта формула описана в Википедии .
Для каждой точки вычислите ее соответствующую точку на новой плоскости как
newpoint = dot(rmat, point)
, где функция dot
выполняет умножение матриц.
Это, конечно, не уникально; как упоминалось в ответе Петерка, существует бесконечное число возможных поворотов, которые могли бы превратить плоскость, нормальную к M
, в плоскость, нормальную к N
. Это соответствует тому факту, что после выполнения описанных выше шагов вы можете поворачивать плоскость вокруг N
, и ваши точки будут находиться в разных местах, оставаясь в одной плоскости. (Другими словами, каждое вращение, которое вы можете совершить в соответствии с вашими условиями, соответствует описанной выше процедуре, за которой следует еще один поворот вокруг N
.) Но если вам все равно, где в плоскости находятся ваши точки, я думаю, это вращение вокруг общей оси - это самый простой способ просто поместить точки в плоскость, в которой они вам нужны.
Если у вас нет M
, но у вас есть координаты точек в начальной плоскости относительно начала координат в этой плоскости , вы можете вычислить начальный вектор нормали из двух точек 'позиции x1
и x2
как
M = cross(x1, x2)
(вы также можете использовать unitcross
здесь, но это не имеет никакого значения). Если у вас есть координаты точек относительно начала координат, которого нет на плоскости, вы все равно можете это сделать, но вам понадобятся три позиции:
M = cross(x3-x1, x3-x2)