问题描述
在数学上,我通过以下步骤做到了这一点:
- 以参数方式定义线的 (x,y,z) 坐标。例如(x,z) = (1+t,2+3t,1-t)
- 将曲面定义为函数。例如z = f(x,y)
- 将线中 x、y 和 z 的值代入曲面函数。
- 通过求解,我将能够得到表面和线的交点
我想知道是否有在 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)
请注意,这种线框和线图的组合处理不好,橙色线的哪一部分应该在曲面的蓝色线线下方。
另请注意,对于此类问题,可能有从 0 到 +∞ 的任意数量的解决方案。这取决于实际表面。 fmin
找到局部最优,这可能是具有 target_func(t_opt)=0
的全局最优,也可能不是。更改初始猜测 x0
可能会改变 fmin
找到的局部最优值。