使用Python检查圆扇区中是否存在点

问题描述 投票:2回答:1

我知道在网上也问过这个问题,但遗憾的是不在Python环境中。在网上看,我发现了这个(Link)并从那里开始研究它。由于我正在使用Pyglet,我将该函数编写为线程。但首先,我告诉你我的想法和想要完成的事情:

enter image description here

P =雪碧球员位置

M =鼠标位置

C =一个虚圆,其半径为P和M之间的距离。

0,1,2,3,4,5,6,7 =精灵可以拥有的方向

a =一个方向与另一个方向之间的角度= 45°

S =与精灵方向对应的圆的截面。简单来说,如果S存在于S中,则方向等于1

start,end =开始角度和结束角度

所以,在函数中,我插入了一个while循环。后来,我不得不计算半径是:

while mpc_thread:
    radius = math.hypot(mpx - cpx, mpy - cpy) + 20

mpx,mpy =鼠标位置(X,Y)

cpx,cpy = Sprite Player Position(X,Y)

我用math.hypotLink)。我加了20,所以半径稍微超过了鼠标的位置。

然后我添加了一个for循环来检查每个方向的圆圈部分:

while mpc_thread:
    radius = math.hypot(mpx - cpx, mpy - cpy) + 20
    for ang_obj in range(0, fchar):
        reference_angle = 360 // fchar * ang_obj
        s_angle = reference_angle - (360 / (fchar / 2))
        e_angle = reference_angle + (360 / (fchar / 2))

fchar =精灵方向的数量,在这种情况下为8

为了找出每个方向的起始和终止角度,我将搭接角度除以方向数量的两倍。然后我将结果减去/添加到参考角度。

从这里开始出现问题。写在我发布第一个链接的方式,if函数没有检测到任何东西,如果我进入否定(我得到一个错误。然后我搜索了一个解决方案,并从user7048690的答案中找到了这个(Link)。这个函数,我遇到了一个新问题(数学域错误)。所以我用math.sqrt更改了cmath.sqrt,它运行了。但是出现了一个新问题。也就是说,总是遵循这个答案,if函数将FPS大幅降低到0/1现在我不知道要去哪里。你能帮我解决这个问题吗?我应该如何正确地建立这个功能并且正常工作?我希望我理解我的问题是什么意思。

python geometry pyglet
1个回答
2
投票

找到最佳方向的最简单方法是计算从玩家位置到鼠标位置的线与从玩家位置到8点的直线之间角度的余弦值。 必须找到与“鼠标”方向具有最小角度的方向矢量。 0度的余弦为1,180°的余弦为-1。因此,具有最大余弦的方向是可以找到的方向。

计算余弦的最简单方法是dot product

通常,2个矢量的点积等于2个矢量之间的角度的余弦乘以两个矢量的幅度(长度)。

dot( A, B ) == | A | * | B | * cos( angle_A_B ) 

由此得出,2个单位矢量的点积等于2个矢量之间角度的余弦,因为单位矢量的长度是1。

uA = normalize( A )
uB = normalize( B )
cos( angle_A_B ) == dot( uA, uB )

二维向量A和B的dot product可以通过2次乘法和1次加法计算:

dotAB = Ax * Bx + Ay * By  

设置一个包含8个标准化方向的列表:

dir = [(0, 1), (0.707, 0.707), (1, 0), (0.707, -0.707),
       (0, -1), (-0.707, -0.707), (-1, 0), (-0.707, 0.707)]

找到“最佳”方向,这是角度最近的方向或最大余弦的方向:

dx, dy = mpx - cpx, mpy - cpy
max_i = max([i for i in range(len(dir))], key = lambda i: dx*dir[i][0] + dy*dir[i][1])

最后max_i包含搜索的方向。

注意算法不计算和比较角度的余弦,它比较余弦和半径的乘积。 dx*dir[i][0] + dy*dir[i][1]radius * cos(alpha)的eqault。

搜索到的点最终是:

radius = math.hypot(mdir_x, mdir_y) + 20
X = (dir[max_i][0] * radius, dir[max_i][1] * radius)

© www.soinside.com 2019 - 2024. All rights reserved.