簡體   English   中英

用Python檢查圓扇區中是否存在一個點

[英]Check whether a point exists in circle sector or not with Python

我知道在網上和這里已經有人問過這個問題,但不幸的是在 Python 環境中沒有。 在網上查看,我發現了這個( 鏈接),並從那里開始研究它。 由於我使用的是 Pyglet,因此我將該函數編寫為線程。 但首先,我向您展示我的想法和想要實現的目標:

在此處輸入圖片說明

P = 精靈玩家位置

M = 鼠標位置

C = 一個假想的圓,其半徑為 P 和 M 之間的距離。

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

a = 一個方向和另一個方向之間的夾角 = 45°

S = 對應於精靈方向的圓的截面。 簡單來說,如果 S 中存在 M,則方向等於 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 = Sprite 方向的數量,在本例中為 8

為了找出每個方向的開始和結束角度,我將搭接角度除以方向數量的兩倍。 然后我將結果減去/添加到參考角度。

問題從這里開始。 以我發布第一個鏈接的方式編寫,if 函數沒有檢測到任何內容,如果我輸入為負值(,我得到一個錯誤。然后我搜索了一個解決方案,並從 user7048690 的答案中找到了這個( 鏈接)。修改的功能,我得到了一個新的問題(數學域錯誤)。因此,我改變math.sqrtcmath.sqrt ,和它的工作,但一個新的問題出現了,即,始終遵循這個問題的答案,IF函數大大降低FPS到 0/1。現在我不知道去哪里。你能幫我解決這個問題嗎?我應該如何正確構建函數並正常工作?我希望我理解我的問題的意思。

找到最佳方向的最簡單方法是計算從玩家位置到鼠標位置的線與從玩家位置到 8 個點的線之間的夾角的余弦。
必須找到與“鼠標”方向具有最小角度的方向向量。 0 度的余弦為 1,180° 的余弦為 -1。 所以具有最大余弦的方向就是要找到的方向。

計算余弦的最簡單方法是

通常,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 的可以通過 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)

最后搜索到的點是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM