[数学]捻じれて縺れてこんがらかるの続き、計算編です。
まず、お互いの直線をベクトルと見なし、その外積を求めます。
この外積は何を意味するかというと、前回の平行な面における法線となっています。
この法線がわかれば、平行な面どうしの距離を計算する事が出ケイます。
それぞれの面から適当な点を1つづつ取り、bの面からaの面へ向かうベクトルを作ります。

この時、cと法線ベクトルの内積を求めれば、お互いの面の距離がわかります。
内積は、あるベクトル成分をどれだけ持っているか、という計算にも使えるわけです。
この辺のからくりがわからなくても、cと法線ベクトルが直角ならば、
aの面とbの面がぴったりくっついている、というのがわかればいいです。
ということで、こんな感じのソースになります。
int LineHitCheck(const Vec3 &a1, const Vec3 &a2, const Vec3 &b1, const Vec3 &b2){
Vec3 va = a1 - a2;
Vec3 vb = b1 - b2;
Vec3 nv = outer(va, vb);
Vec3 vc = a1 - b1;
if (nv.x == 0 && nv.y == 0 && nv.z == 0){
// 平行or同一の場合
Vec3 nv2 = outer(va, vc);
if (nv2.x == 0 && nv2.y == 0 && nv2.z == 0){
return 同一;
}else{
return 平行;
}
}else{
// 交差orねじれの場合
if (inner(vc, nv) == 0){
return 交差;
}else{
return ねじれ;
}
}
}
平行だったときの場合は飛ばしましたが、直線Aと直線Bが同一ということは、
直線B上にあるすべての点が直線A上にあるということです。
ですから、直線Aの一点と直線Bの一点を結ぶベクトルは、常に直線Aベクトルと0度or180度であり、
外積を求めると必ず零ベクトルになります。
ねじれの直線の距離は、法線ベクトルを正規化してcベクトルとの内積を求めると出ます。
カプセルの当たり判定で求める事があるかもしれません。
[数学]捻じれて縺れてこんがらかる の続きです。
今回は軽くおさらいです。
ベクトルを使うに当たり、三次元空間の内積、外積を解説します。
・内積
別名、スカラー積ともよばれ、ベクトルaとベクトルbの内積は一次元の数値となります。
要は、ベクトルじゃないよ、ってことです。
なお、内積が0になるときは、掛け合わせたベクトルが直交するときです。
これは二次元における内積と同じです。
なお、計算式は以下のようになります。
x、y、zそれぞれを掛け合わせてたします。
struct Vec3{
int x, y, z;
};
int inner(const Vec3 &a, const Vec3 &b){
return a.x * b.x + a.y * b.y + a.z * b.z;
}
・外積
別名、ベクトル積で、ベクトルaとベクトルbの内積はベクトルとなります。
この外積で出てくるベクトルはベクトルa、ベクトルbの両方に直交します。
前を表すベクトルと、上を表すベクトルから右を表すベクトルを作り出せます。
ここで、前と上を表すベクトルは必ずしも直行しなくてよいことが重要です。
なお、外積の結果が零ベクトルになることがありますが、
これは掛け合わせたベクトルが同一方向か逆方向を向いているときです。
先ほどの例だと、前を表すベクトルが真上を向いてしまうと、
北極点における東方向という感じで、右方向というのが決まらなくなってしまいます。
こういう場合に零ベクトルとなるわけです。
外積の計算式は以下の通りです。
x→y→z→x というローテーションを意識して、別々を掛けて引くというという形になります。
Vec3 outer(const Vec3 &a, const Vec3 &b){
Vec3 c;
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}