質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4173閲覧

輪郭内にある座標は輪郭内にあると正しく判定したい

kinokoman

総合スコア2

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/08 04:00

輪郭内の内外判定を正しく判定したい

輪郭線と座標をプロットすると輪郭線内に座標があると目でわかるのですが、プログラムが判定すると一部の外積が正になってしまい輪郭線外にあると判定され、うまいこといきません。
外積が正になる部分を回避してうまいこと判定する方法を知りたいです。

輪郭線と判定したい座標点をプロットした画像

Python

1import numpy as np 2import copy 3import pandas as pd 4import matplotlib.pyplot as plt 5 6#多角形の端の座標点を決める 7#(x,y)>(0,0) 8c = [np.array([2,1]),np.array([1,3]),np.array([1,7]),np.array([3,6]),np.array([4,8]),np.array([6,9]),np.array([8,8]),np.array([9,6]),np.array([8,3]),np.array([6,1])] 9 10 11name_list = [] 12for i in range(1,len(c)+1): 13 x = 'c'+str(i) 14 name_list.append(x) 15 #x = 'c{}'.format(i) 16 # = np.array([3,4]) 17 18#求めたい任意座標点の入力 19#(X,Y)>(0,0) 20point =np.array([7 ,8]) 21 22#多角形と任意座標の可視化 23x = [] 24y = [] 25 26for i in range(len(c)): 27 #c[i] = 'c'+str(i) 28 #str(name_list[i-1]) = c[i-1] 29 exec('x_num = c[i][0]'.format(i)) 30 x.append(x_num) 31 exec('y_num = c[i][1]'.format(i)) 32 y.append(y_num) 33x.append(c[0][0]) 34y.append(c[0][1]) 35plt.plot(x, y, label="test") 36plt.plot(point[0], point[1],marker="o",linestyle='None',markersize=6, color='red') 37plt.show() 38 39 40def inside(point,c): 41 #全てのベクトル計算 42 for i in range(1,len(c)+1): 43 if i < len(c): 44 print(c[i]) 45 kakomi = 'vector_c{}c{} = (c[i]-c[i-1])'.format(i,i+1) 46 exec(kakomi) 47 uchigawa = 'vector_c{}point = (point-c[i-1])'.format(i,i) 48 exec(uchigawa) 49 if i == len(c): 50 kakomi2 = 'vector_c{}c1 = (c[0]-c[i-1])'.format(i,i) 51 exec(kakomi2) 52 uchigawa2 = 'vector_c{}point = (point-c[i-1])'.format(i,i) 53 exec(uchigawa2) 54 #全ての外積計算 55 for i in range(1,len(c)+1): 56 if i < len(c): 57 get = 'outer_product_c{}c{}_point = np.cross(vector_c{}c{}, vector_c{}point)'.format(i,i+1,i,i+1,i) 58 exec(get) 59 if i == len(c): 60 get2 = 'outer_product_c{}c1_point = np.cross(vector_c{}c1, vector_c{}point)'.format(i,i,i) 61 exec(get2) 62 63 #外積結果をリストに内包する 64 list =[] 65 for i in range(1,len(c)+1): 66 if i < len(c): 67 s = eval('outer_product_c{}c{}_point'.format(i,i+1)) 68 list.append(s) 69 if i == len(c): 70 t = eval('outer_product_c{}c1_point'.format(i)) 71 list.append(t) 72 print(list) 73 74 #リスト内に1つでも正数があれば、Trueで外側 75 #なければ、Falseで内側 76 if any((x > 0 for x in list)) == True: 77 print('外側にあります') 78 else: 79 print('内側にあります') 80if __name__ == '__main__': 81 x = inside(point,c)

"実行結果"
[array(-17), array(-24), array(8), array(-6), array(-3), array(-1), array(-2), array(-8), array(-12), array(-28)]
外側にあります

このように、内側にある座標も外側判定されてしまいます。
回避する方法をご教授いただけたら幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

判定できればよいということであれば、matplotlib の関数で行えます。

python

1from matplotlib import path 2 3polygon = path.Path( 4 [ 5 [2, 1], 6 [1, 3], 7 [1, 7], 8 [3, 6], 9 [4, 8], 10 [6, 9], 11 [8, 8], 12 [9, 6], 13 [8, 3], 14 [6, 1], 15 ] 16) 17 18print(polygon.contains_point([7, 8])) # True

投稿2021/12/08 04:42

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kinokoman

2021/12/08 15:49

ありがとうございます。 参考にさせていただきま。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問