以下のページを参考にしました。
点の多角形に対する内外判定
単純に実装すると、点が線分上にある場合、図形の向きで結果が逆になってしまいます。
例を挙げます、次の図を見てください
┏━━━━━━━━━━━━┓
┃ /┃
┃ / ┃
┃ / ┃
┃ A / ┃
┃ ・ ┃
┃ / ┃
┃ / ┃
┃ / ┃
┃ / ┃
┃ / B ┃
┃ / ┃
┃/ ┃
┗━━━━━━━━━━━━┛
↑AとBで結果が逆になる。
参考にしたページではそういう仕様で進めているようですが、(図2-3)
直感的には線分上は当たりとするか、
完全に図形に入り込んでいるときのみ当たりにするかのどちらかの方がいいと思います。
今回は、線分上に点がある場合は当たりとする処理にしています。
#module //polygonは実数の配列でも整数の配列でも可 #defcfunc 多角形内外判定 array polygon, int 頂点数, double x, double y count = 0 a_max = 頂点数 * 2 for i,, a_max, 2 始点 = polygon(i), polygon(i + 1) 終点 = polygon((i + 2) \ a_max), polygon((i + 3) \ a_max) if 始点 != 終点{ 判定 = (x - 始点) * (終点.1 - 始点.1) / (終点 - 始点) + 始点.1 - y }else{ 判定 = (x != 始点) || ((y - 始点.1) * (y - 終点.1) > 0) } if 判定 < 0{ if x < 始点 ^ x < 終点{ if 始点 < 終点{ count++ }else{ count-- } } }else: if 判定 == 0{ //点が線分上にある時の処理 return 1 } next return count != 0 #global
#include "a2d.hsp" alcreateImage title "多角形内外判定" repeat stick key if key & 256{ a(頂点数 * 2) = mousex, mousey 頂点数++ } if key & 512{ 頂点数 = limit(頂点数 - 1, 0) } 判定結果 = 多角形内外判定(a, 頂点数, mousex, mousey) redraw 2 alColor 240,240,240 alFillRect 0,0,640,480 alColor 0,0,0 if 判定結果: alColor 200,100,50 alFillPoly a, 頂点数 alColor 50,130,30 alDrawPoly a, 頂点数 alCopyImagetoScreen pos 0, 0 color mes "左クリック: 頂点を作成 mes "右クリック: 最後に作成した頂点を削除 mes ""+mousex+","+mousey + " : " + 判定結果 redraw await 16 loop