有没有一种聪明的方法来确定任意形状内部的点?
Posted
技术标签:
【中文标题】有没有一种聪明的方法来确定任意形状内部的点?【英文标题】:Is there a clever way to determine the points that are inside of an arbitrary shape? 【发布时间】:2022-01-23 23:51:24 【问题描述】:我的目标是确定点是否位于形状内。考虑以下示例:
import numpy as np
from matplotlib import pyplot as plt
import warnings
warnings.filterwarnings('ignore', 'invalid value encountered in sqrt')
r1 = 10
r2 = 4
a = 12 # x shift for circle 2
b = -4 # y shift for circle 2
theta = np.arange(0, 2*np.pi, 0.0006)
r1_complex = r1*np.exp(1j*theta)
r1_x, r1_y = np.real(r1_complex), np.imag(r1_complex)
r2_complex = r2*np.exp(1j*theta)
r2_x, r2_y = np.real(r2_complex) + a, np.imag(r2_complex) + b
fig, ax = plt.subplots()
ax.plot(r1_x, r1_y)
ax.plot(r2_x, r2_y)
ax.set_aspect('equal')
ax.grid()
plt.show()
输出
我想找到橙色圆圈内的蓝色圆圈的点。如果可能的话,最好不要迭代地尝试找到它。
对于这种情况,我可以很容易地确定橙色圆圈内的点,因为我知道圆的方程。将代码修改为:
import numpy as np
from matplotlib import pyplot as plt
import warnings
warnings.filterwarnings('ignore', 'invalid value encountered in sqrt')
r1 = 10
r2 = 4
a = 12 # x shift for circle 2
b = -4 # y shift for circle 2
theta = np.arange(0, 2*np.pi, 0.0006)
r1_complex = r1*np.exp(1j*theta)
r1_x, r1_y = np.real(r1_complex), np.imag(r1_complex)
r1_inside_y = np.logical_and(r1_y < np.sqrt(r2**2 - (r1_x - a)**2) + b, r1_y > -np.sqrt(r2**2 - (r1_x - a)**2) + b)
r2_complex = r2*np.exp(1j*theta)
r2_x, r2_y = np.real(r2_complex) + a, np.imag(r2_complex) + b
fig, ax = plt.subplots()
ax.plot(r1_x, r1_y)
ax.plot(r2_x, r2_y)
ax.plot(r1_x[r1_inside_y], r1_y[r1_inside_y])
ax.set_aspect('equal')
ax.grid()
plt.show()
输出
产生我正在寻找的东西。有没有办法在不知道圆方程的情况下得到同样的结果?也许是一种算法,或者numpy
操作的巧妙方法?
编辑
我所说的任意形状是一种具有 N 个点的封闭形状。考虑这张图片:
我想知道红线范围内的黑线点。对于这个例子,这个算法应该找到两个点,蓝色的 x4 和 x5 点。并且点 x1, x2, ... xN 将是两个形状共享同一原点的坐标点。
【问题讨论】:
你在不知道方程的情况下画了圆,你想找到相交点吗?我的直觉是,最好的办法是根据圆的形状估计圆的方程,然后找到相交点。我猜这在计算上会便宜得多。 如何定义任意形状?如何检查点是否在任意形状内? @GabeMorris 看看at this answer 或者,如果你觉得懒惰或不喜欢数学挑战......你可以在黑色背景上绘制填充白色的Y
多边形,看看你的X
点是什么颜色. docs.opencv.org/4.x/d6/d6e/…
这应该很快...***.com/a/58228861/2836621
【参考方案1】:
事实证明,这个算法已经在 matplotlib.path 模块中进行了标准化。您可以使用Path
类产生相同的结果。考虑对上述代码进行以下更改:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import path
r1 = 10
r2 = 4
a = 12 # x shift for circle 2
b = -4 # y shift for circle 2
theta = np.arange(0, 2*np.pi, 0.0006)
r1_complex = r1*np.exp(1j*theta)
r1_x, r1_y = np.real(r1_complex), np.imag(r1_complex)
stacked1 = np.stack((r1_x, r1_y), axis=1) # A list of coordinates
r2_complex = r2*np.exp(1j*theta)
r2_x, r2_y = np.real(r2_complex) + a, np.imag(r2_complex) + b
stacked2 = np.stack((r2_x, r2_y), axis=1) # A list of coordinates
p = path.Path(stacked2)
r1_inside = p.contains_points(stacked1)
fig, ax = plt.subplots()
ax.plot(r1_x, r1_y)
ax.plot(r2_x, r2_y)
ax.plot(r1_x[r1_inside], r1_y[r1_inside])
ax.set_aspect('equal')
ax.grid()
plt.show()
这会在不了解形状的数学属性的情况下生成相同的图像。
【讨论】:
这里的问题是算法真的很慢。我将不得不对我做事的方式做出一些改变,因为它太慢了。以上是关于有没有一种聪明的方法来确定任意形状内部的点?的主要内容,如果未能解决你的问题,请参考以下文章