<p>这个解决方案与已经发布在这里的解决方案相对类似,但我认为它更高效、更优雅、更容易理解,这就是为什么尽管有相似之处,我还是发布了它</p>
<p>如前所述,min(max(…)公式很难解析地解决此问题,这就是为什么scipy.optimize很适合</p>
<p>该解决方案基于<a href="https://math.stackexchange.com/questions/330269/the-distance-from-a-point-to-a-line-segment">https://math.stackexchange.com/questions/330269/the-distance-from-a-point-to-a-line-segment</a>中概述的点与有限线段之间距离的数学公式</p>
<pre><code>import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, NonlinearConstraint
def calc_distance_from_point_set(v_):
#v_ is accepted as 1d array to make easier with scipy.optimize
#Reshape into two points
v = (v_[:2].reshape(2, 1), v_[2:].reshape(2, 1))
#Calculate t* for s(t*) = v_0 + t*(v_1-v_0), for the line segment w.r.t each point
t_star_matrix = np.minimum(np.maximum(np.matmul(P-v[0].T, v[1]-v[0]) / np.linalg.norm(v[1]-v[0])**2, 0), 1)
#Calculate s(t*)
s_t_star_matrix = v[0]+((t_star_matrix.ravel())*(v[1]-v[0]))
#Take distance between all points and respective point on segment
distance_from_every_point = np.linalg.norm(P.T -s_t_star_matrix, axis=0)
return np.sum(distance_from_every_point)
if __name__ == '__main__':
#Random points from bounding box
box_1 = np.random.uniform(-5, 5, 20)
box_2 = np.random.uniform(-5, 5, 20)
P = np.stack([box_1, box_2], axis=1)
segment_length = 3
segment_length_constraint = NonlinearConstraint(fun=lambda x: np.linalg.norm(np.array([x[0], x[1]]) - np.array([x[2] ,x[3]])), lb=[segment_length], ub=[segment_length])
point = minimize(calc_distance_from_point_set, (0.0,-.0,1.0,1.0), options={'maxiter': 100, 'disp': True},constraints=segment_length_constraint).x
plt.scatter(box_1, box_2)
plt.plot([point[0], point[2]], [point[1], point[3]])
</code></pre>
<p>示例结果:</p>
<p><a href="https://i.stack.imgur.com/8qxEF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8qxEF.png" alt="enter image description here"/></a></p>