LoginSignup
13
12

More than 5 years have passed since last update.

扇形と点の当たり判定

Last updated at Posted at 2012-03-26

AS3版

AS3
public function hitTestArcPoint(cx:Number, cy:Number, rad:Number, startAng:Number, endAng:Number, px:Number, py:Number):Boolean {
    var dx:Number = px - cx;
    var dy:Number = py - cy;
    var sx:Number = Math.cos(startAng);
    var sy:Number = Math.sin(startAng);
    var ex:Number = Math.cos(endAng);
    var ey:Number = Math.sin(endAng);
    if(sx * ey - ex * sy > 0) {
        if(sx * dy - dx * sy < 0) return false; // second test
        if(ex * dy - dx * ey > 0) return false; // third test
        return true; // all test passed
    } else {
        if(sx * dy - dx * sy > 0) return true; // second test
        if(ex * dy - dx * ey < 0) return true; // third test
        return false; // all test failed
    }
}

Java版

Java
public boolean hitTestArcPoint(float cx, float cy, float rad, float startAng, float endAng, float px, float py) {
    float dx = px - cx;
    float dy = py - cy;
    float sx = (float) Math.cos(startAng);
    float sy = (float) Math.sin(startAng);
    float ex = (float) Math.cos(endAng);
    float ey = (float) Math.sin(endAng);
    if(sx * ey - ex * sy > 0) {
        if(sx * dy - dx * sy < 0) return false; // second test
        if(ex * dy - dx * ey > 0) return false; // third test
        return true; // all test passed
    } else {
        if(sx * dy - dx * sy > 0) return true; // second test
        if(ex * dy - dx * ey < 0) return true; // third test
        return false; // all test failed
    }
}

・最初に円で判定をする (first test)
・次に開始角に対して直線で判定する (second test)
・最後に終了角に対して直線で判定する (third test)

どれか一つでも外れれば接触なしと判定します。
円の判定にはお馴染みピタゴラスの定理、
直線の判定には差分ベクトルの外積を使いました。
ただし角度が180度を超えていると正しく判定できないので条件を反転しています。

面積の小さい順に並べておくとささやかな高速化になります。

13
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12