Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Geometry with Unity

2 034 vues

Publié le

Geometry with Unity

Publié dans : Ingénierie
  • Soyez le premier à commenter

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で幾何がやれます ○ このスライドの前準備をするといい感じになる ○ 図形っぽい話だけど他に無さそうな機能だったら 自分で実装できる!すごい! ⚫ ある図形的操作は調べれば割と出るので、 自分のやりたい手順を分割してそれぞれ調べて実装、 っていう感じになるかなあ

×