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

使用Python检查圆扇区中是否存在点,python,geometry,pyglet,Python,Geometry,Pyglet,我知道,在网上和这里已经有人问过这个问题,但不幸的是,在Python环境中没有。在网上,我找到了这个()并从那里开始了我的工作。因为我使用的是Pyglet,所以我将函数作为线程编写。但首先,我要向你们展示我的想法和想要实现的目标: p=精灵玩家位置 M=鼠标位置 C=一个假想圆,其半径为p和M之间的距离 0,1,2,3,4,5,6,7=精灵可以具有的方向 a=一个方向和另一个方向之间的角度=45° S=对应于精灵方向的圆截面。简单地说,如果M存在于S中,则方向等于1 开始,结束=开始角度和结束

我知道,在网上和这里已经有人问过这个问题,但不幸的是,在Python环境中没有。在网上,我找到了这个()并从那里开始了我的工作。因为我使用的是Pyglet,所以我将函数作为线程编写。但首先,我要向你们展示我的想法和想要实现的目标:

p=精灵玩家位置

M=鼠标位置

C=一个假想圆,其半径为p和M之间的距离

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

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

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

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

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

while mpc_thread:
    radius = math.hypot(mpx - cpx, mpy - cpy) + 20
mpx,mpy=鼠标位置(X,Y)

cpx,cpy=精灵玩家位置(X,Y)

我使用了
math.hypot
,多亏了这个()。我加了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的答案中找到了这个()。修改了函数,我得到了一个新问题(数学域错误).所以我用
cmath.sqrt
更改了
math.sqrt
,它成功了。但是出现了一个新问题。那就是,始终遵循这个答案,if函数将FPS大幅降低到0/1。现在我不知道该怎么办。你能帮我解决这个问题吗?我应该如何正确构建函数并正常工作?我希望我理解w我的问题是什么意思。

找到最佳方向的最简单方法是计算从玩家位置到鼠标位置的直线与从玩家位置到8点的直线之间的夹角的余弦。
必须找到与“鼠标”方向夹角最小的方向向量。 0度的余弦是1,180度的余弦是-1。所以余弦最大的方向就是要找到的方向

计算余弦的最简单方法是

通常,两个向量的点积等于两个向量之间的夹角的余弦乘以两个向量的大小(长度)

dot(A,B)==|A |*| B |*cos(角度| A | B)
因此,2个单位向量的点积等于2个向量之间夹角的余弦,因为单位向量的长度为1

uA=正常化(A)
uB=正常化(B)
cos(角度A\u B)=点(uA,uB)

二维向量A和B的值可通过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代表范围内的i(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)

最终搜索点为:

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

谢谢你的回答。我只理解了8个标准化方向的事实。最重要的是,我不理解你是如何得到这些结果的。此外,不幸的是,也许我解释错了,以防你告诉我我用这种方式更正了问题。这8个方向只是玩家被转动,圆圈部分就像是他的视野。因此,鼠标必须在其可见区域内,并且取决于它在玩家周围的位置,精灵的方向会改变为朝向鼠标。我不知道如何解释,因为英语不是我真正的语言。我有(在本例中)玩家的8个图像,对应于图像中的8个方向。我的意图是根据鼠标与玩家位置的比较在不同的图像之间切换。这样,玩家就产生了一种错觉,即玩家自己启动并跟随鼠标。这就是为什么我想到了我上面设计的。为了考试例如,只要鼠标在S,玩家的方向是1。如果鼠标离开S,这意味着它将进入另一个区域,玩家的方向将随之改变,就像之前画的假想圆被分成8个区域(假设代表玩家的视野)。如果鼠标出现在其中一个部分,则玩家将其方向(图纸中8个部分之一)更改为鼠标所在的方向。