画像の輪郭を取得します。

これはサーキットの形状を示す画像ですが、ここから輪郭を構成する点の集合を取得します。サーキットのコースなのでコースアウトした場合、それがわかるように任意の点がコースの内側なのか外側なのかを知る方法も考えます。またゲームをつくる場合、敵の車両も存在するわけですが、そうなると進行方向を取得する方法も考えなければなりません。コース内の任意の点に存在する敵の進行方向を求める方法も考えます。

画像はここからとってきました。

筑波サーキット | わかりやすい モータースポーツ競技規則

左右の余白が大きいので整形したものがこれです。

まず画像ですが、白と青だけかと思ったらそれ以外の色も使われているようです。

以下のメソッドに画像のパスを渡すと「56」が返ってきました。コースの輪郭部分は他の色も混ざっているようです。

それでも背景の青い部分は単色なのでそれ以外の部分だけ集めるとコースの形状を取得することはできそうです。以下のコードでcourse2.pngを取得しました。

これが上記の方法で生成されたファイルです。

次に輪郭部分を取得します。

先ほど取得した画像はコース部分は黒でそれ以外の部分は無色です。そこで黒であるすべてのピクセルを調べて上下左右のどれかが黒ではないならそれが輪郭を構成するピクセルであることがわかります。

コースには外側の境界線と内側の境界線があります。それぞれをわけて、しかも連続している順番に取り出すことはできないのでしょうか?

取得した点は上下左右斜めのどれかで繋がっているので、適当な点をスタート地点にして繋がっているものを順番に取得していくというのはどうでしょうか? これを2回やれば外側と内側の境界線を構成するピクセル座標をすべて取得できそうです。

これは第二引数で指定した色をもつもので最初に見つかったピクセルの座標を返すメソッドです。

これらをまとめると単色(この場合はColor.Black)で塗りつぶされた部分の輪郭を構成するピクセル座標を取得するのであれば以下のようになります。

これでcourse3.pngが得られます。

任意の点が任意の色で塗りつぶされた部分の内側かどうかは以下のコードで確認できます。

しかしBitmap.GetPixelメソッドは時間がかかります。1回だけなら体感時間は一瞬かもしれませんが、短い時間で何度も確認するような処理には適さないと思われます。そこでコースの内部、境界線になるPointをプログラム開始時に取得しておき、以降は取得したリストをつかって判定するようにしたほうがいいかもしれません。

上記の方法で取得した点情報を利用してコースの輪郭部分のみを描画するとともに、クリックされた点がコースの内部かどうかについて判定できるようにします。