今更ながら周りの影響で、QucikBox2Dをいじってます。@alumican_net さんが書かれたブログがわかりやすいので拝見してますが、『 QuickBox2DやBox2DFlashAS3での衝突判定をグループ分け 』という記事で以下のような記述がありました。
自分と何かが衝突するかどうかは、自分のmaskBitsと相手のcategoryBitsの論理積をとって計算できる。結果が0なら衝突しない、0以外なら衝突する。
普段あまり使わないので「論理積ってなに?」って状態だったんで調べてみると、大重美幸さんのActionScript3.0入門ノートにわかりやすい解説がありました。
ビット単位の論理和では値を2進数に換算して各ビットごとに比較し、どちらかが1ならば1にします。たとえば、6(2進数で110)と5(2進数で101)のビット単位の論理和は7(111)になります。同様にビット単位の論理積では両方が1のときに1にし一方が0ならば0にします。6と5のビット単位の論理積は4(100)になります。
2進数における桁のシフトは2のn階乗で変化します。次のサンプルで使われているrgbToHex()はRGBの各色の値から0xFFFFFFの形式の16進数に変換する関数です。
なるほど!ということで、実際に計算してみました。
・●と▲
maskBits:0x0007(0111) & categoryBits:0x0004(0100) >> 4(0100):衝突する
・●と■
maskBits:0x0007(0111) & categoryBits:0x0008(1000) >> 0(0000):衝突しない
・●と●
maskBits:0x0007(0111) & categoryBits:0x0002(0010) >> 2(0010):衝突する
・▲と●
maskBits:0x0007(0111) & categoryBits: 0x0002(0010) >> 2(0010):衝突する
・▲と■
maskBits:0x0007(0111) & categoryBits:0x0008(1000) >> 0(0000):衝突しない
・▲と▲
maskBits:0x0007(0111) & categoryBits: 0x0004(0100) >> 4(0100):衝突する
・■と●
maskBits:0x0001(0001) & categoryBits: 0x0002(0010) >> 0(0000):衝突しない
・■と▲
maskBits: 0x0001(0001) & categoryBits: 0x0004(0100) >> 0(0000):衝突しない
・■と■
maskBits: 0x0001(0001) & categoryBits: 0x0008(1000) >> 0(0000):衝突しない
ふむふむ。確かに先の引用通り「結果(論理積)が0なら衝突しない、0以外なら衝突する。」になっています。
そこで●を categoryBits:0x0001, maskBits:0x0003 に変更してみました。すると・・・
・●と▲
maskBits:0x0003(0011) & categoryBits:0x0004(0100) >> 0(0000):衝突しない
・▲と●
maskBits:0x0007(0111) & categoryBits: 0x0001(0001) >> 1(0001):衝突する
Here is the rule for a collision to occur:
uint16 catA = fixtureA.filter.categoryBits;
uint16 maskA = fixtureA.filter.maskBits;
uint16 catB = fixtureB.filter.categoryBits;
uint16 maskB = fixtureB.filter.maskBits;
if ((catA & maskB) != 0 && (catB & maskA) != 0)
{
// fixtures can collide
}
つまりAとBを比較する時に「それぞれを基準に計算した結果が、どちらも0でない場合に衝突する」ということなんんですね。上に書いた●と▲の場合とも合致しますね。納得。
以下のサイトを参考にしました。感謝。