Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Geometry with Unity

1,982 views

Published on

Geometry with Unity

Published in: Engineering
  • Be the first to comment

Geometry with Unity

  1. 1. Unityで幾何を やる話 KMC-ID:ten
  2. 2. 自己紹介 ⚫ ID:ten ⚫ 京大情報学科3回計算機 ⚫ Twitter:@ten986,@ten986_2600 ⚫ ゲーム制作をしているつもり ⚫ 競プロやったことないです
  3. 3. 近況
  4. 4. 近況
  5. 5. 近況2 ⚫ これは財布の中身です
  6. 6. 近況3
  7. 7. Unityで幾何を やる話 KMC-ID:ten
  8. 8. 幾何 ⚫ 図形的なことをします ○ 点と線分の距離 ○ 点と多角形の内外判定 ○ 多角形の面積
  9. 9. おにぎりのわぎり ⚫ 「Unity1週間ゲームジャム」参加作品 ⚫ おにぎりを円形に切る ⚫ 直線によって切る ⚫ 円に近い/面積が大きいほど高得点 ⚫ https://unityroom.com/games/round_slice
  10. 10. 今日話すこと ⚫ おにぎりのわぎりの実装の説明 ⚫ Unityで幾何をするための知見
  11. 11. 前準備 ⚫ Unityで幾何をやるための前準備 ⚫ PolygonCollider2Dを 判定する多角形として用いる
  12. 12. 前準備 ⚫ PolygonCollider2DのパスをVector2[]に変換しておく ⚫ GetPathという関数があります
  13. 13. 前準備 ⚫ PolygonCollider2Dのパスの座標は 「transformを適用する前の座標」 ⚫ ワールド座標を取得したいなあ ⚫ さっき取得した座標にtransformを適用する ⚫ TransformPointという関数があります
  14. 14. おにぎりのわぎりの実装 1. おにぎりを切る 2.面積を測る(面積が大きいほど高得点) 3.円っぽさを測る(円に近いほど高得点)
  15. 15. おにぎりを切る ⚫ unity-sprite-cutterを使った ○ 凸多角形を直線で切れる ○ 若干改造して 単純な多角形に拡張&バグ取り ⚫ http://baba-s.hatenablog.com/entry/2017/12/31/163100
  16. 16. おにぎりを切る ⚫ 中のコードを見た ⚫ 幾何なんだけど、それ以上に Unityの闇の部分に触れてる ⚫ ので、説明は割愛 ⚫ ちなみにAsset Storeに もっといいやつがあるっぽい
  17. 17. 面積を測る ⚫ さっき取得した多角形の座標を元に面積を測る ⚫ このサイトを参考にした ⚫ https://imagingsolution.net/math/calc_n_point_area/
  18. 18. 面積を測る ⚫ さっきのサイトによると 右のようになるらしい ⚫ 座標は取得できるので、 あとは実装するだけ!
  19. 19. 面積を測る ⚫ 実装(数式をそのまま写したくらい) ⚫ 引数はパスとtransform
  20. 20. 円っぽさを測る ⚫ (これは結構難しかった) ⚫ 円っぽさってなんやねん ⚫ まず定義します
  21. 21. 円っぽさを測る ⚫ 多角形内部の任意の点において ⚫ 外周のうち最も近い点との距離 ⚫ 外周のうち最も遠い点との距離 ⚫ この2つの距離の比の最大値 ⚫ 真円度っていう概念があるらしい ○ その定義に基づいてるので妥当っぽい?
  22. 22. 円っぽさを測る ⚫ これを実装するには? ⚫ 点と多角形の内外判定 ⚫ 点と線分の最も近い距離(っていうか距離) ⚫ 点と線分の最も遠い距離
  23. 23. 点と多角形の内外判定 ⚫ 以下のQiitaを参考にした ⚫ https://qiita.com/ykob/items/6118b8e2e7ddcd8b6355 ⚫ 点と多角形の各点とのなす角の合計が360°になる 場合、その点が多角形に内包されている、ということ になるらしい。
  24. 24. 点と多角形の内外判定 ⚫ 実装 ⚫ ほぼ写した
  25. 25. 点と線分の最も近い距離 ⚫ 以下のQiitaを参考にした ⚫ https://qiita.com/yellow_73/items/bcd4e150e7caa0210 ee6
  26. 26. 点と線分の最も近い距離 ⚫ 記事によると、点と線分上の点との距離の2乗は 下に凸の2次関数になる ⚫ それのある範囲内の最小値を求めるのは高校数学~ ○ 頂点が範囲内に含まれていれば頂点 ○ そうでないなら範囲の端っこのどっちか
  27. 27. 点と線分の最も近い距離 ⚫ 実装 ⚫ 写(ry
  28. 28. 点と線分の最も遠い距離 ⚫ 記事によると、点と線分上の点との距離の2乗は 下に凸の2次関数になる ⚫ ある範囲内の最大値は最小値より簡単 ○ 範囲の端っこのどっちかが必ず最大値
  29. 29. 点と線分の最も遠い距離 ⚫ 実装 ⚫ 2つの端点との距離のMaxを取ってる
  30. 30. 円っぽさを測る ⚫ 道具は全部用意した! ⚫ ということでいよいよ円っぽさを測ります ⚫ 次のスライドの再掲する手順で実装します
  31. 31. 円っぽさを測る(再掲) ⚫ 多角形内部の任意の点において ⚫ 外周のうち最も近い点との距離 ⚫ 外周のうち最も遠い点との距離 ⚫ この2つの距離の比の最大値 ⚫ 真円度っていう概念があるらしい ○ その定義に基づいてるので妥当っぽい?
  32. 32. 何はともあれ ⚫ まずはパスをワールド座標に変換しておきましょう
  33. 33. 多角形内部任意の点をとる ⚫ 多角形内部の任意の点とは? ⚫ 任意の点を取ることは不可能 ⚫ 多角形内にある程度細かく点をとりましょう
  34. 34. 多角形内部任意の点をとる ⚫ 多角形の上下左右端をとる ⚫ その内部に細かく点をとろう
  35. 35. 多角形内部任意の点をとる ⚫ 縦横それぞれn=30(+1)分割します ⚫ 961個の等間隔な点それぞれについて内部か判定 ⚫ 内部なら以降の 判定をする
  36. 36. そういえば ⚫ 2つの距離の値から比を求める関数を用意しておく ⚫ 実装は、まぁはい。 ⚫ 評価関数を変えたくなったときに便利なのでね
  37. 37. 内部の点それぞれを見る ⚫ 内部の点それぞれについて、 ○ 外周のすべての線分との距離の最小値を求める ○ 外周のすべての線分との距離の最大値を求める ○ 距離の最小値÷距離の最大値(つまり比)を求める ○ その値が今までで最大なら記録
  38. 38. 内部の点それぞれを見る ⚫ 最大値を取るために初期化 ⚫ 適当な点を取って、最大値を-∞にしとく ○ いつもの
  39. 39. 点と線分との距離の最小値 ⚫ パス内の線分を順にみていく ⚫ 距離が最小なら記録
  40. 40. 点と線分との距離の最大値 ⚫ パス内の線分を順にみていく ⚫ 距離が最大なら記録
  41. 41. 距離と距離の比を計算 ⚫ 距離の最小値÷距離の最大値(図ではValue)を求める ⚫ その値が最大なら記録 ⚫ すべての点で見たら、 maxValueを返す
  42. 42. 円っぽさを測る ⚫ 以上の手順で求めたmaxValueが求めたい円っぽさ ⚫ お疲れ様でした!!! ⚫ スライドの半分、円っぽさの計測じゃねえか
  43. 43. まとめ ⚫ Unityで幾何がやれます ○ このスライドの前準備をするといい感じになる ○ 図形っぽい話だけど他に無さそうな機能だったら 自分で実装できる!すごい! ⚫ ある図形的操作は調べれば割と出るので、 自分のやりたい手順を分割してそれぞれ調べて実装、 っていう感じになるかなあ

×