python - 平面拟合到 4 个(或更多)XYZ 点

标签 python geometry least-squares plane

我有 4 个点,它们非常接近一个平面 - 这是 1,4-二氢吡啶循环。

我需要计算 C3 和 N1 到由 C1-C2-C4-C5 构成的平面的距离。 计算距离还可以,但拟合平面对我来说很难。

1,4-DHP 循环:

1,4-DHP cycle

1,4-DHP循环,另一种观点:

1,4-DHP cycle, another view

from array import *
from numpy import *
from scipy import *

# coordinates (XYZ) of C1, C2, C4 and C5
x = [0.274791784, -1.001679346, -1.851320839, 0.365840754]
y = [-1.155674199, -1.215133985, 0.053119249, 1.162878076]
z = [1.216239624, 0.764265677, 0.956099579, 1.198231236]

# plane equation Ax + By + Cz = D
# non-fitted plane
abcd = [0.506645455682, -0.185724560275, -1.43998120646, 1.37626378129]

# creating distance variable
distance =  zeros(4, float)

# calculating distance from point to plane
for i in range(4):
    distance[i] = (x[i]*abcd[0]+y[i]*abcd[1]+z[i]*abcd[2]+abcd[3])/sqrt(abcd[0]**2 + abcd[1]**2 + abcd[2]**2)
    
print distance

# calculating squares
squares = distance**2

print squares

如何使 sum(squares) 最小化?我尝试过最小二乘法,但这对我来说太难了。

最佳答案

这听起来不错,但您应该用 SVD 代替非线性优化。下面创建惯性张量 M,然后使用 SVD 得到平面的法线。这应该是最小二乘拟合的近似值,并且速度更快,更可预测。它返回点云中心和法线。

def planeFit(points):
    """
    p, n = planeFit(points)

    Given an array, points, of shape (d,...)
    representing points in d-dimensional space,
    fit an d-dimensional plane to the points.
    Return a point, p, on the plane (the point-cloud centroid),
    and the normal, n.
    """
    import numpy as np
    from numpy.linalg import svd
    points = np.reshape(points, (np.shape(points)[0], -1)) # Collapse trialing dimensions
    assert points.shape[0] <= points.shape[1], "There are only {} points in {} dimensions.".format(points.shape[1], points.shape[0])
    ctr = points.mean(axis=1)
    x = points - ctr[:,np.newaxis]
    M = np.dot(x, x.T) # Could also use np.cov(x) here.
    return ctr, svd(M)[0][:,-1]

例如:在 (10, 100) 处构造一个二维云,它在 x 方向上很薄,在 y 方向上大 100 倍:

>>> pts = np.diag((.1, 10)).dot(randn(2,1000)) + np.reshape((10, 100),(2,-1))

拟合平面非常接近 (10, 100),法线非常接近 x 轴。

>>> planeFit(pts)

    (array([ 10.00382471,  99.48404676]),
     array([  9.99999881e-01,   4.88824145e-04]))

关于python - 平面拟合到 4 个(或更多)XYZ 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12299540/

相关文章:

matlab - 二变量最小二乘函数逼近

python - 使用 curve_fit 拟合数据

python - 如何测试 stanfordnlp 是否在 GPU 上运行?

python - 如何在 R 或 Python 中制作 3d(4 变量)三元(金字塔)图?

c++ - 在空间图上使用 boost 凸包

javascript - 用六边形填充圆(不同的方法)

algorithm - 给定多个圆和一个点,如何找到哪个圆包含该点

python - django 模型上的 who 和 who

python - json schema Draft 7 python 中的多种自定义类型

MATLAB 曲线拟合 - 最小二乘法 - 使用高次错误 "fit"