アカデメイア実験室のラボノートには勉強したことのメモを書いていきます。
目標はUnity Learnで3Dを学んで面白そうな何か作ってみることです(雑)
最終的には記事にも価値が出るようなものにしたいですが、何しろ不慣れなので、当面は行動記録として「投稿すること」を優先しようと思います。
こうしたほうがいいぞ!とかあればTwitterで絡んでください。
今日の内容は3DGameを作る(C#編)です
Roll-a-ballを基準にゲームを作ろうとしています
今回は散布アルゴリズム検討をしたよ、という記録です。
つくりたかったもの
グリッド内にいい感じにランダム散布してくれるプログラム
マップにオブジェクトを置くときに、このプログラムではこちらが完全に位置を指定してあげるんですが、いい感じに均等風に置きたいよね、と思ったので、方法を考えていました。
ただ今回は、ランダム出現させたいのは自然物ではなくて、ターゲットです。
つまり次のような条件です。
・ランダムとはいえ、出待ちされないことが目的なので、別に全体として(エイト・クイーンゲームのきれいな配置のように)人為的に見えてもよい。
・マップ中に攻略に関係のない広い空間が残ると困る。
一般的な解法:
ポアソン円盤サンプリング
これは自然の木とかの配置で使う、計算量が少なくて最小距離を保証してランダム散布するアルゴリズムです。
[今回使いたくない理由] 最小距離をある程度広げないとほぼ完全ランダムになるので広い空間が残るが、最小距離を広げ過ぎると配置に失敗する。
対策案1 : 最初に考えたのは「磁石を浮かべた時のように配置したいから、斥力系の平衡配置問題として解けないか?」
→乱雑さは再帰演算回数で調整。ちょっと作ってみたら均等に近くなるまで再帰演算するので、特に今回の用途では激重でした。むしろ計算が疎な時であればポアソン円盤サンプリングよりきれいに行けそう。
対策案2 : 「ImageJのDistanceMapみたいに距離計算して遠くから配置したらいいのでは?」
→1つ追加するごとに毎回マップ更新するのである程度重いけれど、大きさが小さければ誤差程度、きれいに配置したい時斥力系問題よりは軽い
[最終的に選択したアルゴリズム]
いちおう距離マップを利用した散布をC#で作成してみました。
ポアソン円盤サンプリングの距離の最適化も今度探してみたいですね。
計算量とか境界ケースとか比較できたら会社のブログ記事とかに載せてもらおうかなと考えています。
以上、今日はここまで
またよろしくお願いします。