2017-03-20 43 views
0

讓我開始說明,雖然我的問題是編程性質,但是卡住的部分有點數學問題。所以我不確定這是否是發佈它的正確位置,但我不確定其他位置。確定點是否在六邊形內的函數

我想要定義一些布爾函數,如果點(x,y)在某個形狀內,則返回true,否則返回false。要澄清的是,下面的代碼將工作定義內半徑r1和外徑r2的環(環):

def ring(pos): 
    (x, y) = pos 
    rsq = x ** 2 + y ** 2 
    return (r1 ** 2 < rsq < r2 ** 2) 

我的問題是,如果有人可以幫我想出了一個巧妙的方法來定義這是一個六角形區域的函數。具體來說,我想定義一個邊長爲s(這是直徑的一半)的六角形區域,以原點爲中心。理想情況下,它也將被定向爲使得頂部和底部是側面,與x軸平行。

+1

如果您在搜索引擎中輸入「point inside hexagon」,您會獲得大量示例。 (一種流行的方法是使用相同的算法來檢測一個點是否在任何凸多邊形內) – UnholySheep

+0

你是完全正確的,出於某種原因,我逐漸淘汰了一點,沒有找到合適的搜索詞。我會研究那些 – user129412

+0

@UnholySheep雖然這是一個非常特殊的情況,可能允許一個更簡單的解決方案。 –

回答

3

使用對稱性來獲得到第一象限,然後簡單的數學(畢達哥拉斯就足夠了),檢查點是否都「下面的對角線」(Y = SQRT(3)⋅(S,其具有 - x)的)和「低於頂邊」(其具有y = sqrt(3)/ 2 ⋅ s)。

>>> def hexagon(pos): 
     x, y = map(abs, pos) 
     return y < 3**0.5 * min(s - x, s/2) 

演示:

>>> s = 13 
>>> for y in range(-s, s+1): 
     print(' '.join('.X'[hexagon((x, y))] for x in range(-s, s+1))) 

. . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . X X X X X X X X X X X X X . . . . . . . 
. . . . . . X X X X X X X X X X X X X X X . . . . . . 
. . . . . . X X X X X X X X X X X X X X X . . . . . . 
. . . . . X X X X X X X X X X X X X X X X X . . . . . 
. . . . . X X X X X X X X X X X X X X X X X . . . . . 
. . . . X X X X X X X X X X X X X X X X X X X . . . . 
. . . X X X X X X X X X X X X X X X X X X X X X . . . 
. . . X X X X X X X X X X X X X X X X X X X X X . . . 
. . X X X X X X X X X X X X X X X X X X X X X X X . . 
. . X X X X X X X X X X X X X X X X X X X X X X X . . 
. X X X X X X X X X X X X X X X X X X X X X X X X X . 
. X X X X X X X X X X X X X X X X X X X X X X X X X . 
. X X X X X X X X X X X X X X X X X X X X X X X X X . 
. . X X X X X X X X X X X X X X X X X X X X X X X . . 
. . X X X X X X X X X X X X X X X X X X X X X X X . . 
. . . X X X X X X X X X X X X X X X X X X X X X . . . 
. . . X X X X X X X X X X X X X X X X X X X X X . . . 
. . . . X X X X X X X X X X X X X X X X X X X . . . . 
. . . . . X X X X X X X X X X X X X X X X X . . . . . 
. . . . . X X X X X X X X X X X X X X X X X . . . . . 
. . . . . . X X X X X X X X X X X X X X X . . . . . . 
. . . . . . X X X X X X X X X X X X X X X . . . . . . 
. . . . . . . X X X X X X X X X X X X X . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . 
+0

令人印象深刻的解決方案和非常酷的表示。 –

+0

@EricDuminil帶了我幾個嘗試,讓圖片看起來不錯:-)。我希望我們有一個「真正的」等寬字體(等寬和高)... –

+0

真的很酷的解決方案。也許你可以稍微詳細說明下面的對角線和上邊緣部分,但另一方面,讀者應該能夠弄清楚他/她自己。 – user129412

0

圍繞六角形創建邊界框,高度是中心拐角之間的距離讓我們說a,寬度是左右小面之間的距離可以說b。
如果你有一個六邊形的預定大小,你可以很容易地得到它周圍的4個三角形的面積。
因此,你可以測試你的點是否在這些三角形之一,如果不是,那麼它是在六角形。

________ 
| /\ | 
|*/\ *| This is an illustration of the above suggestion 
|/ \ | The * are points outside the hexagon. 
|/  \| 
|  | 
|  | 
|\  /| 
| \ /| 
| *\/*| 
|___\/___| 
+1

然後問題變成如何測試它是否在三角形內,但如果三角形更容易,您可以將六角形「拆開」爲6個,並在那裏做 –

+0

三角形更容易,是的,你也可以這樣做,取決於你想運行多少測試,在我看來,4比6好。 –

+0

不會有5個測試,但?一個檢查是否在廣場內,然後每個三角形一個(仍然比6好) –

1

您的解決方案基本上是基於極座標。由於戒指或圓圈以原點爲中心,因此您並不在乎θ:您只需檢查r是否在[0,r_max]之內,或者是[r_min,r_max]之內。

您可以使用polar definition of an hexagon並檢查r是否在[0,r_hexagon(θ)]之內。

下面是與numpy的和matplotlib一個例子:

import numpy as np 
import matplotlib.pyplot as plt 
import math 


theta = np.arange(0, 2 * math.pi, 0.01) 

sixty_d = math.pi/3 


def hexagon(theta): 
    return math.sqrt(3)/(2 * math.sin(theta + sixty_d - 
             sixty_d * math.floor(theta/sixty_d))) 

hexagon = np.vectorize(hexagon) 

ax = plt.subplot(111, projection='polar') 
ax.plot(theta, hexagon(theta)) 
ax.set_rmax(1.5) 
ax.set_rticks([0.5, 1, 1.5]) 
ax.grid(True) 

ax.set_title("Hexagon in polar coordinates", va='bottom') 
plt.show() 

它顯示:enter image description here

您可以用上面的hexagon(theta)得到最大半徑。 theta可以用math.atan2(y, x)來計算。

1

我的兩個美分:

def inside(pos, R): 
    import numpy as np 
    r = R * np.sqrt(3)/2 
    try: # thanks to @stefan-pochmann 
     phi = np.arctan(pos[1]/pos[0]) 
    except ZeroDivisionError: 
     phi = 0.0 
    length = np.sqrt(pos[0] ** 2 + pos[1] ** 2) 
    for i in range(3): 
     rot = 2 * np.pi/3.0 * i 
     new_phi = phi + rot 
     new_pos = (length * np.sin(new_phi), length * np.cos(new_phi)) 
     if abs(new_pos[0]) <= np.sqrt(R ** 2 - r ** 2) and abs(new_pos[1]) <= r: 
      return True 
    return False 

它假定六邊形圍繞(0, 0)中心並且R是規定的圓半徑和r內切一個。

它不是環算法的實現。它使用包圍盒

+0

@StefanPochmann確實;指數也是相反的。我希望現在可以正常工作。 –

+0

我沒有得到一個六邊形:http://ideone.com/Kdy6Vu –

+0

@StefanPochmann在旋轉之前忘了將度數轉換爲弧度。有趣的形狀,但。由於某種原因,我現在缺少2個角落(http://ideone.com/cptiEK)。嗯 –

相關問題