2017-11-06 17 views
2

多角形パスに含まれるすべてのポイントを見つけるためにMatplotlibを使用しようとしていますが、より具体的には、私のパスは長方形であり、その点はその下にある均一なグリッドにあります。次のテストスクリプトでは、ポリゴンの一番上の行にある点をポリゴンの一部として考慮しませんが、残りの点の点を考慮します。Matplotlib path.contains_pointsは、いくつかのエッジのポイントではfalseを返しますが、他のポイントではfalseを返します。

コード:

import matplotlib.path as mpltPath 

polygon = [(5,5),(10,5),(10,10),(5,10)] 
width =11 
height =11 

points = [[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0], \ 
      [0,1],[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[11,1],\ 
      [0,2],[1,2],[2,2],[3,2],[4,2],[5,2],[6,2],[7,2],[8,2],[9,2],[10,2],[11,2],\ 
      [0,3],[1,3],[2,3],[3,3],[4,3],[5,3],[6,3],[7,3],[8,3],[9,3],[10,3],[11,3],\ 
      [0,4],[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],\ 
      [0,5],[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],\ 
      [0,6],[1,6],[2,6],[3,6],[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],\ 
      [0,7],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],\ 
      [0,8],[1,8],[2,8],[3,8],[4,8],[5,8],[6,8],[7,8],[8,8],[9,8],[10,8],[11,8],\ 
      [0,9],[1,9],[2,9],[3,9],[4,9],[5,9],[6,9],[7,9],[8,9],[9,9],[10,9],[11,9],\ 
      [0,10],[1,10],[2,10],[3,10],[4,10],[5,10],[6,10],[7,10],[8,10],[9,10],[10,10],[11,10],\ 
      [0,11],[1,11],[2,11],[3,11],[4,11],[5,11],[6,11],[7,11],[8,11],[9,11],[10,11],[11,11]] 


path = mpltPath.Path(polygon) 
inside = path.contains_points(points) 
print(inside) 

ようになり、上記のコードは、私は、結果の行5は、それに続くもののような真の値が含まれていることを期待する

[False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False False False False False False False False] 

を返します。ポリゴンの座標を5から4.9に変更すると、私は期待した結果を得ます。

私は、これが機能を誤用または誤解することと関連していると想定していますが、それが何でどのようになっているかはわかりません。

EDIT:ポリゴンの端にあるポイントに対してcontains_pointsがFalseを返しているはずです。私の例では、上端[5,5] - [10,5]ではこの動作が見られますが、他のエッジ([5,5] - [5,10]、[5,10] - [10,10]、および[10,10] - [10,5])。これらの3つの他の辺は、真の値を持つ最初の列と最後の列に対応し、上の出力例で真の値を含む最後の行に対応します。この問題は明らかに不一致です。

+0

本当の質問は、なぜ「5」が縦の稜線に沿った経路に含まれていますが、水平の稜線には含まれていないのでしょうか? – ImportanceOfBeingErnest

+0

これはバグだと思います。ポリゴン「ポリゴン[:: - 1]」の向きを変更すると、動作は期待通りです。ただし、10行目が '真'を表示していることを除いては、 – jojo

+1

私はちょうどコメントして、それを言っていた。バグをプロジェクトページに提出して報告します。 –

答えて

2

更新:今はオープンissue in matplotlibです。国境上に線を除く


contains_pointsのような機能のために期待される動作であるかもしれません。 しかし、この場合には、多角形の境界上の点は、一貫した方法で処理されていません。あなたがライン5を与える例で

境界上の点の排除を示したが、行5 10およびライン10はボーダーポイントの包含を示す。

polygon[::-1]でパスを描くと、逆の向きになり、10行目以外のすべての境界で期待通りの動作が行われ、ここで再び包含が適用されます。

私には明らかな論理パターンはありません。しかし、1つがあっても、この動作は確かに混乱しており、修正する必要があります。


今、あなたはまだあなたのポリゴンの下宿に置くためにポイントを回避することにより、目的の動作を取得することができます。あなたはcontains_points機能のradius属性を使用して行うことができます。

半径をパスがわずかに大きくまたは小さくすることができます。あなたがそのようなRADIUS属性のためにいくつかの小さな正または負の値を提供する場合ので

# ... 
path = mpltPath.Path(polygon) 
inside = path.contains_points(points,radius=0.1) 

print(inside) 

あなたが得る:

[False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False False False False False False False False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False True True True True True True False 
False False False False False False False False False False False False] 

注意を、半径が正であるべきかどうか負の場合は方向によって異なります。この詳細についてはhereをご覧ください。経験則として:正の半径は、パスが反時計回りになるとパスを展開し、パスが時計回りになるとパスを縮めます

+1

私はこれがこれに似たものだと考えましたが、この制限が上端にのみ存在する理由はありますか? 2番目の最後の行はまた、[10,10] [5,10]辺に置かれているポイント、および最初の列と最後の列が真の値を持つので、これによって影響を受けます。 –

+1

@AlexBあなたがここでくれたこのコメントは、本当に興味深い質問の部分であり、それは質問テキスト自体の一部でなければなりません。 – ImportanceOfBeingErnest

+0

ええと、これは本当に面白いですし、私は@ ImportanceOfBeingErnestに同意します。実際には、**上の行だけがそのように動作します**。ポリゴンの向きを変更した場合、 '[(5,5)、(5,10)、(10,10)、(10,5)] 'は期待どおりに動作しますが、国境を含むこれは、実際には、contains_pointsが何らかの形でポリゴンの向きに敏感であることを示しています。ちょっと変だ。 – jojo

関連する問題