问题描述
我知道在网上以及这里都已经有人问过这个问题,但不幸的是,在Python环境中却没有.从网上看,我发现了这个(链接),然后从那里开始研究.由于我使用的是Pyglet,因此我将该函数编写为线程.但是首先,我向您展示我的想法和想要实现的目标:
I am aware that on the net and also here the question has already been asked, but unfortunately not in the Python environment. Looking on the net, I found this (Link) and from there I started working on it. Since I'm using Pyglet, I wrote the function as a thread. But first, I show you what I thought and wanted to accomplish:
P =精灵播放器位置
P = Sprite Player Position
M =鼠标位置
C =一个假想的圆,其半径为P和M之间的距离.
C = An imaginary circle, having as its radius the distance between P and M.
0、1、2、3、4、5、6、7 =精灵可以具有的方向
0, 1, 2, 3, 4, 5, 6, 7 = Directions that the sprite can have
a =一个方向和另一个方向之间的角度= 45°
a = Angle between one direction and another = 45°
S =对应于精灵方向的圆的截面.简而言之,如果M存在于S中,则方向等于1
S = Section of the circle corresponding to the sprite direction. In simple words, if M is present in S, the direction is equal to 1
开始,结束=起始角度和终止角度
start, end = Start Angle and End Angle
因此,在函数中,我插入了一个while循环.后来,我不得不计算出半径何时为:
So, in the function, I inserted a while loop. Later, I had to calculate when the radius was:
while mpc_thread:
radius = math.hypot(mpx - cpx, mpy - cpy) + 20
mpx,mpy =鼠标位置(X,Y)
mpx, mpy = Mouse position (X, Y)
cpx,cpy =精灵播放器位置(X,Y)
cpx, cpy = Sprite Player Position (X, Y)
由于这个原因,我使用了math.hypot
(链接).我加了20,所以半径稍微超过了鼠标的位置.
I used math.hypot
thanks to this (Link). I added 20, so that the radius slightly exceeded the position of the mouse.
然后我添加了一个for循环来检查每个方向的圆形部分:
Then I added a for loop to check the circle section for each direction:
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 = Sprite方向的数量,在这种情况下为8
fchar = Amount of Sprite directions, in this case 8
要找出每个方向的起始和终止角度,我将重叠角除以方向数的两倍.然后我将结果减去/加到参考角度.
To find out the starting and ending angle for each direction, I divided the lap angle by twice the number of directions. Then I subtracted / added the result to the reference angle.
从这里开始出现问题.以我发布第一个链接的方式编写,if函数没有检测到任何东西,并且如果我输入否定(,我得到一个错误.然后我搜索了一个解决方案,发现了这个问题(),来自user7048690的回答.修改了函数,我遇到了一个新的问题(数学域错误),所以我用cmath.sqrt
更改了math.sqrt
,它起作用了,但是又出现了一个新问题,就是说,总是紧跟着这个答案,if函数就大幅度地发展了.将FPS降低为0/1.现在我不知道要去哪里了,您能帮我解决这个问题吗?我应该如何正确构建函数并正常工作呢?希望我理解我的意思.
From here on the problems started. Writing in the way I posted the first link, the if function didn't detect anything and if I went in negative (, I got an error. I then searched for a solution and found this (Link) from the answer of user7048690. Modified the function, I got a new problem (math domain error). So I changed math.sqrt
with cmath.sqrt
, and it worked. But a new problem had arisen. That is, always following that answer, the if function drastically reduced FPS to 0/1. Now I don't know where to head. Can you help me with this problem? How should I build the function correctly and work properly? I hope I understood what I meant by my question.
推荐答案
查找最佳方向的最简单方法是计算从播放器位置到鼠标位置的直线与从播放器位置的直线之间的角度的余弦值定位到8点.
必须发现与鼠标"方向成最小角度的方向矢量.0度的余弦为1,180°的余弦为-1.因此,具有最大余弦的方向就是要找到的方向.
The easiest way to find the best direction is to calculate the cosine of the angle between the line from the player position to the mouse position and the line from the player position to the 8 points.
It has to be found that direction vector which has the smallest angle to the "mouse" direction.The cosine of 0 degrees is 1 and the cosine of 180° is -1. So the direction with the greatest cosine is the direction to be found.
最简单的计算余弦的方法是 dot 产品.
The easiest way to calculate the cosine is the dot product.
通常,两个向量的 dot 乘积等于两个向量之间的角度的 cosine 乘以两个向量的大小(长度).
In general the dot product of 2 vectors is equal the cosine of the angle between the 2 vectors multiplied by the magnitude (length) of both vectors.
dot( A, B ) == | A | * | B | * cos( angle_A_B )
因此,由于一个单位矢量的长度为1,所以两个单位矢量的 dot 乘积等于两个矢量之间的角度的 cosine .
This follows, that the dot product of 2 unit vectors is equal the cosine of the angle between the 2 vectors, because the length of a unit vector is 1.
uA = normalize( A )
uB = normalize( B )
cos( angle_A_B ) == dot( uA, uB )
二维矢量A和 点积 B可以通过2次乘法和1次加法来计算:
The dot product of 2-dimensional vectors A and B can be calculated by 2 multiplications and 1 addition:
dotAB = Ax * Bx + Ay * By
设置具有8个标准化方向的列表:
Set up a list with the 8 normalized directions:
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)]
找到最佳"方向,即最接近该角度或该角度的最大余弦的方向:
Find the "best" direction, this is the direction with the closest angle or the greatest cosine of the angle:
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
包含搜索到的方向.
Finally max_i
contains the searched direction.
请注意,该算法不会计算和比较角度的余弦,而是会比较余弦和半径的乘积. dx*dir[i][0] + dy*dir[i][1]
等价于 radius * cos(alpha)
.
Note the algorithm doesn't calculate and compare the cosine of the angles, it compares product of the cosine and the radius. dx*dir[i][0] + dy*dir[i][1]
is eqault to radius * cos(alpha)
.
这篇关于使用Python检查圆扇区中是否存在点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!