有没有一种聪明的方法来确定任意形状内部的点?

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()

这会在不了解形状的数学属性的情况下生成相同的图像。

【讨论】:

这里的问题是算法真的很慢。我将不得不对我做事的方式做出一些改变,因为它太慢了。

以上是关于有没有一种聪明的方法来确定任意形状内部的点?的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种聪明的方法来处理 NuGet 中的包依赖关系?

WPF命令行参数,一种聪明的方法?

有没有啥聪明的方法可以在 python 中组合重叠路径?

有没有聪明的方法来解析 xml 到列表?

使用 Java DocumentListener 的更聪明的方法

有没有更聪明的方法将布局绑定到片段?