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度を超えていると正しく判定できないので条件を反転しています。
面積の小さい順に並べておくとささやかな高速化になります。