とりあえずの点 vs 多角形の当たり判定

所用で点vs多角形の当たり判定が必要になったのでメモしておきます。

基本的な考え方は以下を参考にしています。
http://poltergeist.web.fc2.com/hit_test.html

関数と使い方

/**
 * 点 vs 多角形の当たり判定
 * 
 * @param  {Vector2}    point 対象点
 * @param  {...Vector2} vertices 多角形頂点
 * @return {Boolean} 範囲内かどうか
 */
function hitTestPolygon(point, ...vertices) {
  const peripheryVecs = []; // 多角形外周ベクトル群
  const vertToPointVecs = []; // 各頂点~対象点までのベクトル群
  vertices.forEach((v, i)=> {
    // 外周ベクトル生成
    const dest = (vertices[i+1] != null) ? vertices[i+1] : vertices[0];
    peripheryVecs.push({
      x: dest.x - v.x,
      y: dest.y - v.y,
    })
    // 各頂点から点へのベクトル生成
    vertToPointVecs.push({
      x: point.x - v.x,
      y: point.y - v.y,
    })
  })

  // 上記二種のベクトルの外積Z軸成分を計算
  // 全て正もしくは負になれば範囲内という扱い
  let signFlag;
  const isOutsideRange = peripheryVecs.some((vec, i)=> {
    const pVec = vertToPointVecs[i];
    const crossZ = (vec.x * pVec.y) - (vec.y * pVec.x);
    if (signFlag != null) {
      if (signFlag !== (crossZ > 0)) {
        // 符号が変わった場合、領域外になるのでループ抜ける
        return true;
      }
    } else {
      signFlag = (crossZ > 0);
    }
  })

  return !isOutsideRange;
}

見ての通り第2引数以降はrestパラメータ(可変長引数)になっており、五角形なら頂点オブジェクトを5つ、八角形なら8つ渡すみたいな感じで使います。
(ただし頂点同士のなす角度が180以上だとNG)

point, verticesは共にプロパティにxyをもったオブジェクトであれば何でもOKです。

const mouse = {
  x: 20,
  y: 200
}

if (hitTestPolygon(mouse, 
  {x:20, y: 20},
  {x:20, y: 30},
  {x:40, y: 30})) {
  console.log('hit!')
}

使い方サンプル

まだ最適化しきれてないような気がしますが、とりあえずということで…

おまけ

Mapオブジェクトを渡したいとき。(es2017以降?)

const vertexMap = new Map([
  ["bl", new Vector2()],
  ["br", new Vector2()],
  ["tr", new Vector2()],
  ["tl", new Vector2()],
])

hitTestPolygon(p, ...vertexMap.values())

個別に記事にするほどでもないphina.jsのtipsまとめ

phina.jsでの開発で、わざわざ記事にまとめるほどでもない(あるいは現在その元気が無い)けど、メモしておきたいことをあったらGistRunstantにとりあえず残してます。ただどちらもバラけてて見通しが悪いので、リンクを随時ここにまとめていこうと思います。基本的には自分用。

続きを読む

メンタルケア個人的メモ

基本的に上に行くほど大事

行動

  • 外に出ろ
  • 散歩しろ(できたら朝or午前中、太陽のある時間帯)
    • ジョギングのような激しめの運動はあまりおすすめしない
  • 太陽の光を浴びろ
  • 睡眠はしっかりとれ
    • 昼夜逆転は避けろ
    • コーヒーは夕方以降は避けろ
  • 2日に一回は湯船に浸かれ
  • 粗食を心がけろ、食事は無理にとるな
    • 満腹になると余計なことを考えがち
  • リラックスできる環境に身を置け
    • 人それぞれだが個人的にはカフェやイートインスペースなど
  • 家にいると全くダメダメな時もある。その場合とにかく外に出ろ
    • いつでも外に出られる格好でいろ(=部屋着で過ごすな)
    • ノートPCやスマホなどは充電しておけ
  • できたら日誌をつけろ
    • 不安になったタイミングをチェックしろ
  • 外に出ろ

考え方

  • 物事のハードルはめちゃくちゃ下げろ
    • 朝起きてカーテン開けるだけで上出来だ
  • 今までどうにかなったことを思い出せ
  • 先のことをあまり想像するな
    • 不安・めんどうくささが湧き上がってしまう
  • ボーっとすることを自分に許せ
  • 暗い気持ちになったらだいたい体調不良や疲れのせいだ、寝ろ
  • 選択肢はむやみに増やすな
    • 決断もエネルギーを消費するぞ