Python 查询变换球体上最近的点

Python 查询变换球体上最近的点,python,geometry,computational-geometry,Python,Geometry,Computational Geometry,给定一个球体和一个空间点的4x4变换矩阵,我想找到球体表面上最近的点 通常我会在点和球体的中心之间画一条线,并使用球体的半径来得到我的解,但这里我处理的是一个非均匀缩放的球体。下面是Python中的一个快速示例: import numpy as np from numpy.core.umath_tests import inner1d # 4x4 transform matrix of a sphere with the following components: # Scale XYZ =

给定一个球体和一个空间点的4x4变换矩阵,我想找到球体表面上最近的点

通常我会在点和球体的中心之间画一条线,并使用球体的半径来得到我的解,但这里我处理的是一个非均匀缩放的球体。下面是Python中的一个快速示例:

import numpy as np
from numpy.core.umath_tests import inner1d

# 4x4 transform matrix of a sphere with the following components:
# Scale XYZ = 1,5,1 (Scaled only in Y axis to keep this example simple)
# Rotation XYZ = 0,0,45 (Simple tilt for this example)
# Position XYZ = -1,3,0 (Position along XY plane, again for simplicity)
M = np.array([[ 0.70710678,  0.70710678,  0.        ,  0.        ],
              [-3.53553391,  3.53553391,  0.        ,  0.        ],
              [ 0.        ,  0.        ,  1.        ,  0.        ],
              [-1.        ,  3.        ,  0.        ,  1.        ]])

# Query point p0
p0 = np.array([-2,6,0])

# Transform the point into a unit sphere
I = np.linalg.inv(M)
p1 = np.array(p)-M[3,:3]
p1 = np.dot(p1,I)

# Normalize the point so it is on the surface of the unit sphere
mag = np.sqrt(inner1d(p1,p1)) # magnitude
p1 /= mag

# Transform back into 3D space
p1 = np.dot(p1,M[:3,:3]) + M[3,:3] #result [-1.65653216, 4.96959649, 0.]


当查询点已经接近球体时,此解决方案速度很快,效果很好,但距离较远时效果不太好。如上图所示:点p2将是所需的结果

您想看看David Eberley的“点到椭圆、椭球或椭圆的距离” 超椭球体“ (.) 最终,您将找到二维椭圆的四次多项式的根,并且 三维椭球体的6次多项式的根,所以这是 这决不是一个简单的问题


考虑到这种复杂性,您可能希望寻找一个近似结果,例如,通过对椭球体进行网格划分并寻找最近的网格顶点。

我不知道下面的迭代过程是否有效,但我凭直觉想到了这一点。也许值得一试

  • 从给定的点,画一条线到椭圆ID的中心,并获得与曲面的交点

  • 在交点处构造法线平面,并将给定点投影到该平面上

  • 将投影连接到中心,找到与曲面的交点,然后从2开始重复,直到收敛

  • 我不知道是否可以保证收敛到最近的点。我所能说的是,当存在收敛时,你已经找到了给定点在曲面上的正交投影

    图中显示了第一次迭代(交叉点为绿色,投影为橙色)

    这可能相当于牛顿的迭代。

    请参阅我的探索