有没有一种聪明的方法来确定任意形状内的点?
Is there a clever way to determine the points that are inside of an arbitrary shape?
我的目标是确定点是否位于形状内部。考虑以下示例:
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 将是两个形状共享相同原点的坐标点。
原来,这个算法已经在matplotlib.path模块中标准化了。您可以使用 Path
class 产生相同的结果。考虑对上述代码进行以下更改:
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()
这会在不了解形状的数学属性的情况下生成相同的图像。
我的目标是确定点是否位于形状内部。考虑以下示例:
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 将是两个形状共享相同原点的坐标点。
原来,这个算法已经在matplotlib.path模块中标准化了。您可以使用 Path
class 产生相同的结果。考虑对上述代码进行以下更改:
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()
这会在不了解形状的数学属性的情况下生成相同的图像。