将平面转换为 XY 平面

Transform plane to XY plane

我正在尝试寻找变换矩阵,它可以让我将给定平面转移到 XY 平面。基于这个 answer,我准备了一个小的 Python 函数来进行这些计算。但是我不明白为什么最终平面不在 XY 中。 你能帮我看看我做错了什么吗?

我的输入平面(3d view):

390.17 * x + -571.67 * y + -4008.29 * z + 2833797.03 = 0
input = [390.17, -571.67, -4008.29, 2833797.03]
z = 0.0973*x - 0.1427*y + 706.9838 

在我看来,要将其转移到 XY 平面,应该先绕 X 轴和 Y 轴旋转。最后一个元素是沿 Z 轴的平移。

基于此answer我准备了我的函数transform_plane()。 (下面的代码)。

结果函数returns新平面:(3d view)

2.19436115e+00  1.61044899e+03  4.06772244e+03 -4.20201320e+04 = 0
out = [2.19436115e+00, 1.61044899e+03, 4.06772244e+03, -4.20201320e+04]
Z = -0.0005*x-0.3959*y+10.3301

看起来,平面只绕了Y轴旋转,要对齐XY,还应该绕X轴旋转。 这是否意味着我忘记了什么?或链接答案中提供的矩阵不足以获得两个不同轴的转换?

编辑: 感谢下面的回答,我能够找到丢失的平方根,但我仍然不明白为什么我的翻译不够。 我的结果不是 Z = 0,而是 Z = 10。在我看来,也许 -d/c 也应该除以平方根。

我的实现:

import numpy as np

def calc_cos_phi(a, b, c):
    return c / sqrt(a*a + b*b + c*c)


def calc_sin_phi(a, b, c):
    return sqrt((a*a + b*b) / (a*a + b*b + c*c))


def calc_u1(a, b, c):
    return b / (a*a + b*b)


def calc_u2(a, b, c):
    return -a / sqrt(a*a + b*b)


def get_transform_matrix(plane):
    a, b, c, d = plane
    cos_phi = calc_cos_phi(a, b, c)
    sin_phi = calc_sin_phi(a, b, c)
    u1 = calc_u1(a, b, c)
    u2 = calc_u2(a, b, c)
    out = np.array([
        [cos_phi + u1 * u1 * (1 - cos_phi)  , u1 * u2 * (1 - cos_phi)           , u2 * sin_phi  ,  0            ],
        [u1 * u2 * (1 - cos_phi)            , cos_phi + u2 * u2 * (1 - cos_phi) , -u1 * sin_phi ,  0            ],
        [-u2 * sin_phi                      , u1 * sin_phi                      ,      cos_phi  , -d / c        ],
        [0                                  , 0                                 , 0             ,  1            ]
    ])
    return out


def transform_plane(plane):
    t = get_transform_matrix(plane)
    t_inv = np.linalg.inv(t)
    new_plane = np.dot(plane, t_inv)
    print("new plane:")
    print(new_plane)
    return new_plane

测试:

plane = [390.17, -571.67, -4008.29, 2833797.03]
plane_xy = transform_plane(plane)

您在这里错过了sqrt

def calc_u1(a, b, c):
   return b / (a*a + b*b)

应该是

def calc_u1(a, b, c):
   return b / sqrt(a*a + b*b)

替换给出 [-1.13686838e-13 0.00000000e+00 4.06760715e+03 -4.19362793e+04] - x 系数几乎为零,平面平行于 OXY(如 z=-1.05