使用 numpy 将 3d 点转换为新坐标系的函数
Posted
技术标签:
【中文标题】使用 numpy 将 3d 点转换为新坐标系的函数【英文标题】:Function to transform 3d points to a new coordinate system with numpy 【发布时间】:2019-03-24 18:33:03 【问题描述】:我在空间中有n
点:
points.shape == (n,3)
我有一个由点O = [ox, oy, oz]
和3 个不同长度的正交向量定义的新坐标系:Ox = [oxx, oxy, oxz], Oy = [oyx, oyy, oyz], Oz = [ozx, ozy, ozz]
。
我怎样才能写出这样的函数?
def change_coord_system(points, O, Ox, Oy, Oz)
return # points in new coordinate system
【问题讨论】:
【参考方案1】:您在原始系统中有 4 个非共面点(其中lx
是第一个向量的长度,依此类推):
(0,0,0), (lx,0,0), (0,ly,0), (0,0,lz)
和他们在新系统中的双胞胎
[ox, oy, oz]
[oxx + ox, oxy + oy, oxz + oz]
[oyx + ox, oyy + oy, oyz + oz]
[ozx + ox, ozy + oy, ozz + oz]
仿射变换矩阵A应该将初始点转换成它们的对点
A * P = P'
用点列向量制作矩阵:
|x1 x2 x3 x4| |x1' x2' x3' x4'|
A *|y1 y2 y3 y4| = |y1' y2' y3' y4'|
|z1 z2 z3 z4| |z1' z2' z3' z4'|
|1 1 1 1| |1 1 1 1|
|0 lx 0 0| |ox oxx + ox . .|
A *|0 0 ly 0| = |oy oxy + oy . .| // lazy to make last columns
|0 0 0 lz| |oz oxz + oz . .|
|1 1 1 1| |1 1 1 1|
要计算A,需要将两个sude乘以P矩阵的逆
A * P * P-1 = P' * Pinverse
A * E = P' * Pinverse
A = P' * Pinverse
因此计算 P 的逆矩阵并将其与右侧矩阵相乘。
编辑:Maple计算的逆矩阵是
[[-1/lx, -1/ly, -1/lz, 1],
[1/lx, 0, 0, 0],
[0, 1/ly, 0, 0],
[0, 0, 1/lz, 0]]
得到的仿射变换矩阵是
[[-ox/lx+(oxx+ox)/lx, -ox/ly+(oyx+ox)/ly, -ox/lz+(ozx+ox)/lz, ox],
[-oy/lx+(oxy+oy)/lx, -oy/ly+(oyy+oy)/ly, -oy/lz+(ozy+oy)/lz, oy],
[-oz/lx+(oxz+oz)/lx, -oz/ly+(oyz+oz)/ly, -oz/lz+(ozz+oz)/lz, oz],
[0, 0, 0, 1]]
Maple sheet view for reference
编辑: 刚刚注意到:Maple 没有删除过多的求和,所以结果应该更简单:
[[(oxx)/lx, (oyx)/ly, (ozx)/lz, ox],
[(oxy)/lx, (oyy)/ly, (ozy)/lz, oy],
[(oxz)/lx, (oyz)/ly, (ozz)/lz, oz],
[0, 0, 0, 1]]
【讨论】:
非常感谢,完美的回答!【参考方案2】:假设我们有两个点,P=[2, 4, 5]
和 Q=[7, 2, 5]
。首先,您必须找到旋转变换矩阵 A 和传输矩阵 B 并应用以下等式
使用numpy的代码是
import numpy as np
# points P and Q
points = np.array([[2,4,5], [7,2,5]])
# suppose that the matrices are
rotation_matrix = np.matrix('1 2 1; 1 2 1; 1 2 1')
b = np.array([1, 1, 1])
def transformation(points, rotation_matrix, b):
for n in range(points.shape[0]):
points[n,0] = rotation_matrix[0,0] * points[n, 0] + rotation_matrix[0,1] * points[n, 1] + rotation_matrix[0,2] * points[n, 2] + b[0]
points[n,1] = rotation_matrix[1,0] * points[n, 0] + rotation_matrix[1,1] * points[n, 1] + rotation_matrix[1,2] * points[n, 2] + b[1]
points[n,2] = rotation_matrix[2,0] * points[n, 0] + rotation_matrix[2,1] * points[n, 1] + rotation_matrix[2,2] * points[n, 2] + b[2]
Output: array([[16, 30, 82],
[17, 27, 77]])
我认为上面的函数给出了新的观点。你可以检查一下。当然,您可以使用 numpy 执行矩阵乘法,但您需要重塑 np.arrays。
【讨论】:
谢谢,但您能否提供一个带有建议签名的实现,即 change_coord_system(points, O, Ox, Oy, Oz) => 新坐标系中的点 @Bolo 这是数学问题而不是编程问题!如果你想要这个函数签名,你必须从 Ox、Oy、Oz 中找到旋转矩阵并在函数内部构造它。如果你不给我更多的细节,我无能为力。 对不起,但我认为你有足够的细节来实现确实会计算旋转矩阵的函数。以上是关于使用 numpy 将 3d 点转换为新坐标系的函数的主要内容,如果未能解决你的问题,请参考以下文章