2009年06月16日

ゲーム数学5(円と線分の当たり判定)

円と線分との当たり判定

ソースを見ていたら、昔作った円と線分との当たり判定の関数が出てきましたので公開してみます。

内容としましては、半径rの円の中心(x, y)(sx1, sy1)(sx2, sy2)を結ぶ線分との当たり判定です。
考え方としては円の中心から線分へ垂直に交わる直線を想定し、その交点を求めます。
その交点は円と直線との最短距離になりますのでその点から円の中心の距離と半径の長さを比べて当たり判定しています。



  /**
   * 円と線分の当たり判定
   */
  public void judgeHitScopeLine(int sx1, int sy1, int sx2, int sy2) {
      int dx, dy;
      
      // 線分の端と端の距離をx,y軸個別に求めます
      int sx = sx2 - sx1;
      int sy = sy2 - sy1;
      
      // x軸方向に位相差が存在する場合は円の中心から線分へ垂直に交わる直線と線分の交点を求めます。
      if(sx != 0) dx = ((y-sy1)*sx*sy + x*sx*sx - sx1*sy*sy) / (sx*sx + sy*sy);
      // 位相差がない場合はsx1=sx2になっているので線分のx方向の位相差はない
      else dx = sx1;
      
      // y軸方向の位相差が存在する場合は円の中心から線分へ垂直に交わる直線と線分の交点を求めます。
      if(sy != 0) dy = ((x-sx1)*sx*sy + y*sy*sy - sy1*sx*sx) / (sy*sy +sx*sx);
      // 位相差がない場合はsy1=sy2になっているので線分のy方向の位相差はない
      else dy = sy1;
      
      // 当たり判定する必要があるか
      if(isjudgeHitScopeLine(sx1, sy1, sx2, sy2)) {
          // 円の中心から求めた交点の距離と半径を比べて当たり判定する
          if((x-dx)*(x-dx)+(y-dy)*(y-dy) < r*r) return true; 
      }
      return false;
  }
  /**
   * 当たり判定するかどうかの判定
   */
  private boolean isjudgeHitScopeLine(int sx1, int sy1, int sx2, int sy2) {
      // 線分の端から円と接触している可能性があるかどうか判定する
      if(x <= (Math.max(sx1, sx2) + r) && x >= (Math.min(sx1, sx2) - r)) {
          if(y <= (Math.max(sy1, sy2) + r) && y >= (Math.min(sy1, sy2) - r)) return true;
      }
      return false;
  }



ラベル:六本木店長
posted by ラクサス at 11:53| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。