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

python中点和曲线之间的距离

如何解决python中点和曲线之间的距离

我有几个点和一条曲线,被描述为两个列表,包括位置。我尝试获取点和曲线之间的差异列表。我试图遵循这个web,但我不明白这个command

X = fmin_cobyla(objective,x0=[0.5,0.5],cons=[c1])

请问在我的案例中正确的论点是什么?

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

data = np.loadtxt('O_Cout.dat',unpack=True,usecols=[0,2])

z_1v1 = np.polyfit(data[0],data[1],2)
f_1v1 = np.poly1d(z_1v1)
# Creating more points on the streamline - defining new time with more steps
x_new = list(np.arange(0,100000,1))
y_new = f_1v1(x_new)

# Plot figure with size
fig,ax = plt.subplots()

ax.scatter(data[0],data[1])

ax.plot(x_new,y_new)


def objective(X):
    x,y = X
    return np.sqrt((x - P[0])**2 + (y - P[1])**2)

def c1(X):
    x,y = X
    return f(x) - y


for i in range(len(data[1])-1):
    P = (data[0][i],data[1][i])
    print(P)

    X = fmin_cobyla(objective,cons=[c1])

    print ('The minimum distance is',objective(X))


# Save the figure
plt.tight_layout()
plt.savefig('OC_parabola.png')

解决方法

您找到的脚本适用于已知函数 f(x) 但 IIUC 您不知道 f(x):您的曲线仅由坐标 (x,y) 定义,而您不知道 f( x) 使得 y=f(x)。

在这种情况下,您可以使用相同的基础知识。

给定一个点 P

enter image description here

和由坐标(x,y)定义的曲线,点P到曲线上一点的距离可以简单地定义为

enter image description here

我们希望最小化,即在定义的域中找到最小值/a。

例如

import numpy as np  
import matplotlib.pyplot as plt

# Here I define a function f(x) to
# generate y coordinates,but let us
# suppose we don't know it and that
# we got only x and y
def f(x):
    return np.cbrt( np.exp(2*x) -1 )

# This is what we really got
x = np.linspace(-2,2,1000)
y = f(x)

# The point P
P = (.5,.5)

fig,ax = plt.subplots(figsize=(7,7))
ax.plot(x,y,lw=4)
ax.plot(*P,'or')
ax.text(
    P[0],P[1],f"  P ({P[0]},{P[1]})",ha='left',va='center',fontsize=15
)
ax.set(
    xlim=(-2,2),ylim=(-2,)
plt.show()

enter image description here

让我们定义函数 d,即点 P 与曲线之间的距离

def distance(x,x0,y0):
    d_x = x - x0
    d_y = y - y0
    dis = np.sqrt( d_x**2 + d_y**2 )
    return dis

现在计算给定 P 和 (x,y) 之间的 d 并找到最小值

from scipy.signal import argrelmin

# compute distance
dis = distance(x,P[0],P[1])
# find the minima
min_idxs = argrelmin(dis)[0]
# take the minimum
glob_min_idx = min_idxs[np.argmin(dis[min_idxs])]
# coordinates and distance
min_x = x[glob_min_idx]
min_y = y[glob_min_idx]
min_d = dis[glob_min_idx]

和绘图结果

fig,7))

ax.plot(x,lw=4)
ax.plot(
    [P[0],min_x],[P[1],min_y],'k--',lw=1,label=f'distance {min_d:.2f}'
)
ax.plot(*P,)
ax.legend()
plt.show()

enter image description here

编辑

改进,可以定义一个简单的函数来返回所有的最小距离,例如

import numpy as np  
import matplotlib.pyplot as plt

def distance(x,y0):
    """
    Return distance between point
    P[x0,y0] and a curve (x,y)
    """
    d_x = x - x0
    d_y = y - y0
    dis = np.sqrt( d_x**2 + d_y**2 )
    return dis

def min_distance(x,P,precision=5):
    """
    Compute minimum/a distance/s between
    a point P[x0,y)
    rounded at `precision`.
    
    ARGS:
        x,y      (array)
        P         (tuple)
        precision (int)
        
    Returns min indexes and distances array.
    """
    # compute distance
    d = distance(x,P[1])
    d = np.round(d,precision)
    # find the minima
    glob_min_idxs = np.argwhere(d==np.min(d)).ravel()
    return glob_min_idxs,d

即使有多个最小值也能工作

def f(x):
    return x**2

x = np.linspace(-2,1000)
y = f(x)

P = (0,1)

min_idxs,dis = min_distance(x,P)

fig,lw=4)
for idx in min_idxs:
    ax.plot(
        [P[0],x[idx]],y[idx]],'--',label=f'distance {dis[idx]:.2f}'
    )
ax.plot(*P,ylim=(-1,3),)
ax.legend()
plt.show()

enter image description here

def f(x):
    return np.sqrt(4 - x**2)

x = np.linspace(-2,21)
y = f(x)

P = (0,0)

min_idxs,)
ax.legend(loc='upper left',bbox_to_anchor=(1,1))
plt.show()

enter image description here

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