我有一个具有一定数量区域的坐标系,类似于此区域:
但是,在我的情况下,不同之处在于,所有区域均具有唯一编号,且大小均相同,并且共有16个区域(因此,每个象限将具有4个完全相同大小的切片)。
我还有一组元组(二维坐标),它们都在(-1,-1)和(1,1)之间。现在,我想检查一下如果映射到坐标系上它们将落入哪个区域(即1到16)。
作为一个初学者,我不知道如何解决这个问题,但是到目前为止,这是我的方法:
进行所有分隔线功能,并检查每个点是否在其上方和下方。忽略决策边界上的那些
例如:象限1具有四个区域。从x轴到y轴(逆时针),我们将它们称为a,b,c和d。
a将是x轴与f1(x)= 0.3333x(红色)之间的区域
在f1和f2之间的b,f2(x)= x(黄色)
在f2和f3之间的c,f3(x)= 3x(蓝色)
在f3和y轴之间d
代码:
def a(p):
if(y > 0 and y < 0.3333x):
return "a"
else:
b(p)
def b(p):
if(y > 0.3333x and y < x)
return "b"
else:
c(p)
def c(p):
if(y > x and y < 3x):
return "c"
else:
d(p)
def d(p):
if(y > 3x and x > 0):
return "d"
注意:为了便于阅读,我只为元组的相应坐标写了“ x”和“ y”,而不是每次都写p [0]或p [1]。另外,如上所述,我假设函数中没有直接存在的项目,因此将其忽略。
现在,这是一个可能的解决方案,但我觉得几乎可以肯定有一个更有效的解决方案。
答案 0 :(得分:2)
由于您在(-1,-1)
和(1,1)
坐标之间进行工作并且将笛卡尔平面平分,所以使用三角函数很自然。在具有2*pi
个角度的单一圆中思考,您将其划分为n
个相等的部分(在本例中为n = 16
)。因此,每个切片具有(2*pi)/16 = pi/8
个Deeges。现在您可以想象一个连接到原点(x, y)
的任意点(0, 0)
,它与x轴成一个角度。要找到该角度,您只需要计算y/x
的反正切。然后,您只需要验证它在哪个角度部分即可。
这是草图:
要直接映射到间隔,可以使用bisect module:
import bisect
from math import atan2
from math import pi
def find_section(x, y):
# create intervals
sections = [2 * pi * i / 16 for i in range(1, 17)]
# find the angle
angle = atan2(y, x)
# adjusts the angle to the other half circle
if y < 0:
angle += 2*pi
# map into sections
return bisect.bisect_left(sections, angle)
用法:
In [1]: find_section(0.4, 0.2)
Out[1]: 1
In [2]: find_section(0.8, 0.2)
Out[2]: 0
答案 1 :(得分:1)
Shapely是一个python库,可以帮助您解决典型的笛卡尔几何问题,但据我所知,它没有一种简单的方法可以基于函数无限期地扩展其Line
对象。
如果还可以,则可以使用Point
模式检查Polygon
中是否有Polygon.contains(Point)
,如下所示:https://shapely.readthedocs.io/en/stable/manual.html#object.contains >