微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

3D python中线和面之间的交点

如何解决3D python中线和面之间的交点

我希望能够找到一条线和一个三维曲面之间的交点。

在数学上,我通过以下步骤做到了这一点:

  1. 以参数方式定义线的 (x,y,z) 坐标。例如(x,z) = (1+t,2+3t,1-t)
  2. 将曲面定义为函数。例如z = f(x,y)
  3. 将线中 x、y 和 z 的值代入曲面函数
  4. 通过求解,我将能够得到表面和线的交点

我想知道是否有在 Python 中执行此操作的方法。我也乐于接受有关解决交集的更简单方法的建议。

解决方法

您可以使用以下代码:

import numpy as np
import scipy as sc
import scipy.optimize
from matplotlib import pyplot as plt

def f(x,y):
    """ Function of the surface"""
    # example equation
    z = x**2 + y**2 -10
    return z

p0 = np.array([1,2,1]) # starting point for the line
direction = np.array( [1,3,-1]) # direction vector

def line_func(t):
    """Function of the straight line.
    :param t:     curve-parameter of the line

    :returns      xyz-value as array"""
    return p0 + t*direction

def target_func(t):
    """Function that will be minimized by fmin
    :param t:      curve parameter of the straight line

    :returns:      (z_line(t) - z_surface(t))**2 – this is zero
                   at intersection points"""
    p_line = line_func(t)
    z_surface = f(*p_line[:2])
    return np.sum((p_line[2] - z_surface)**2)

t_opt = sc.optimize.fmin(target_func,x0=-10)
intersection_point = line_func(t_opt)

主要思想是将代数方程point_of_line = point_of_surface(相交条件)重新表述为一个最小化问题:|point_of_line - point_of_surface| → min。由于表面表示为 z_surface = f(x,y),因此可以方便地仅根据 z 值计算给定 t 值的距离。这是在 target_func(t) 中完成的。然后通过t找到最佳fmin值。

可以通过一些绘图来检查结果的正确性和合理性:


from mpl_toolkits.mplot3d import Axes3D
ax = plt.subplot(projection='3d')

X = np.linspace(-5,5,10)
Y = np.linspace(-5,10)
tt = np.linspace(-5,100)

XX,YY = np.meshgrid(X,Y)
ZZ = f(XX,YY)

ax.plot_wireframe(XX,YY,ZZ,zorder=0)

LL = np.array([line_func(t) for t in tt])
ax.plot(*LL.T,color="orange",zorder=10)
ax.plot([x],[y],[z],"o",color="red",ms=10,zorder=20)

wire frame plot of line and surface

请注意,这种线框和线图的组合处理不好,橙色线的哪一部分应该在曲面的蓝色线线下方。

另请注意,对于此类问题,可能有从 0 到 +∞ 的任意数量的解决方案。这取决于实际表面。 fmin 找到局部最优,这可能是具有 target_func(t_opt)=0 的全局最优,也可能不是。更改初始猜测 x0 可能会改变 fmin 找到的局部最优值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。