2017-03-20 25 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

検索エンジンに "点の内側に六角形"を入力すると、多くの例が得られます。 (1つの一般的なアプローチは、点が凸多角形の内側にあるかどうかを検出するために同じアルゴリズムを使用することです) – UnholySheep

+0

何らかの理由で、私はちょっと段階的に段階的に抜け出し、適切な検索語句を出しませんでした。私はそれらを調べます – user129412

+0

@UnholySheepこれは非常に特殊なケースですが、より単純な解決策を可能にします。 –

答えて

3

yはSQRT(3)⋅(S =有する第一象限に入るために対称性を使用し、単純な数学(ピタゴラスが十分である)点が「対角線の下に」の両方であるか否かをチェックする( - X)を)と"上端の下に"(これはy = sqrt(3)/ 2 を持ちます)。

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

デモ:

+0

という印象的な解決策、そして非常にクールな表現。 –

+0

@EricDuminil画像をすばらしく見せるようにいくつかの試みをしました:-)。私たちは "真の"等幅フォント(等幅と高さ)を持っていればよかったです... –

+0

確かに非常にクールな解決策です。おそらく、あなたは対角線と上端の部分を少し詳しく説明することができますが、一方で読者はそれを理解することができます。 – user129412

0

六角形の周りにバウンディングボックスを作成します。高さは、中央コーナーの間の距離であり、幅は、左右のファセットの間の距離です。
六角形に所定のサイズがある場合、それを囲む4つの三角形の面積を簡単に取得できます。
したがって、ポイントがこれらの三角形のいずれかにあるかどうかをテストできます。そうでない場合は、六角形になります。

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

問題は三角形の内側にあるかどうかをテストする方法になります。三角形が簡単な場合は、6角形を6つに分解してそこに置くことができます –

+0

三角形は簡単ですはい、あなたもそれを行うことができます、実行するテストの数に応じて、4は私の意見では6より良いです。 –

+0

には5つのテストはありませんか? 1つは三角形の中にあるかどうかをチェックする(まだ6よりも良い) –

1

解決策は基本的に極座標に基づいています。リングや円は原点を中心にしているので、については気にしません。rがディスクの場合は[0,r_max]、リングの場合は[r_min,r_max]の範囲内にあるかどうかを確認するだけです。

polar definition of an hexagonを使用し、r[0,r_hexagon(θ)]の内部にあるかどうかを確認できます。

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)を使用することができます

は、ここでnumpyのとmatplotlibの持つ例です。 thetamath.atan2(y, x)で計算できます。

1
>>> 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 . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . 
. . . . . . . . . . . . . . . . . . . . . . . . . . . 

私の2セント:

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)。 Hmmm –

関連する問題