2D で堅牢な光線球交差ルーチンを実装するのに苦労しています。GPUで実行されるため、適切にデバッグできないかなりハッジ関数を一緒にハックしました。私は次のことからインスピレーションを得ました: 円の線分衝突検出アルゴリズム? およびhttp://paulbourke.net/geometry/sphereline/。どこでエラーを探すべきかわかりません。明らかな何かが欠けていますか?実際の円セグメントの衝突に興味があるため、円が線を囲んでいるかどうかを確認する場合は、交点として返されます。
関連するコード スニペットは次のとおりです。
bool CircleSegmentIntersection2d(float2 x0, float2 x1, float2 center, float r) {
float2 d = x1-x0;
float2 f = x0-center;
float a = dot2d(d,d);
float b = 2*dot2d(f,d);
float c = dot2d(f,f)-r*r;
float discriminant = b*b-4*a*c;
if( discriminant < 0 ) {
// no intersection
return false;
} else {
discriminant = sqrt(discriminant);
// either solution may be on or off the ray so need to test both
float sol1 = (-b + discriminant)/(2*a);
float sol2 = (-b - discriminant)/(2*a);
float t0 = min(sol1, sol2);
float t1 = max(sol1, sol2);
if (t1 < 0)
return false;
// Line segment doesn't intersect and on outside of sphere, in which case both values of t will either be less than 0 or greater than 1.
if (0 < t0 && 0 < t1 || t0 > 1 && t1 > 1)
return false;
// Line segment doesn't intersect and is inside sphere, in which case one value of t will be negative and the other greater than 1.
if (t0 < 0 && t1 > 1) {
return true;
}
// Line segment intersects at one point, in which case one value of t will be between 0 and 1 and the other not.
if (t0 < 0 && 0 <= t1 && t1 <= 1) {
return true;
}
// Line segment intersects at two points, in which case both values of t will be between 0 and 1.
if (0 <= t1 && t1 <= 1 && 0 <= t0 && t0 <= 1) {
return true;
}
// Line segment is tangential to the sphere, in which case both values of t will be the same and between 0 and 1.
if (length(t0-t1) < 0.005f) {
return true;
}
}
return false;
}
ここで、dot2d は次のように定義されます。
float dot2d(float2 a, float2 b) {
return a.x*b.x+a.y*b.y;
}
御時間ありがとうございます!