1

立方体/バウンディングボックスの内側または外側にあるかどうかをテストする必要があるオブジェクトを追跡しています。それらが外側にある場合は、光線平面の交差を実行して、立方体の平面の1つ上の点を計算します。光線はボックスの中央から始まり、オブジェクトに向かっています。平面は、立方体を構成する6つの平面の1つです。

私が避けたいのは、6つの平面すべてで光線平面の交差を常にテストしているということです。だから私は賢くて、最初に各平面法線と光線の間の内積を計算すると思いました。次に、角度が最も小さいもの(1に最も近いもの)を選択します。

これは中途半端にしか機能しません。オブジェクトが平面の1つと位置合わせされている場所があり、関数が間違った平面を選択します。ほとんどの場合それは機能します、そして私はそれがなぜであるか疑問に思います。私のアプローチには根本的に何か問題があるに違いないと思います。

これが私の定義した平面で、それぞれにラベルが付いています。座標系の0,0,0は、立方体の1つの角です。

planes = {
    xnear = { normal = {1, 0, 0}, d = 0 },
    xfar = { normal = {-1, 0, 0}, d = cubeSize.x },
    ynear = { normal = {0, 1, 0}, d = 0 },
    yfar = { normal = {0, -1, 0}, d = cubeSize.y },
    znear = { normal = {0, 0, 1}, d = 0 },
    zfar = { normal = {0, 0, -1}, d = cubeSize.z }, 
}

次に、次の関数を使用します。

-- Determine what plane to use for collision testing. The angle is calculated
-- between the plane normal and the direction of the ray
function whatPlane(pos)
local direction = vec3.sub(cubeCenter, pos)
local result
local max = -1
for label, plane in pairs(planes) do
    local dotproduct = vec3.dot(plane.normal, direction)
    if dotproduct > max then
        max = dotproduct
        result = label
    end
end
return result
end

私はここで何が欠けていますか?

すべての平面で衝突テストを実行してから、立方体の中心に最も近い点を選択することもできると思いますが、それは無駄のようです。

4

1 に答える 1

1

立方体が実際に立方体である場合、つまりすべての次元が同じである場合(そして、正多面体の中心にある場合のみ)、あなたの議論は問題ありません。しかし、軸ごとに異なる寸法があるように見えます。

1つの長さがかなり小さい場合(非常に薄いボックスを考えてください)、ほとんどの場合、どの方向を見ても、それらの大きな平面にぶつかり、薄い側面にぶつかることはほとんどありません。

ボックスの正確な長さで方向をスケーリングすると、これを補正できます。つまり、あなたの代わりに、ディビソンが座標によって行われる場所directionを使用します。direction/(cubeSize.x,cubeSize.y,cubeSize.z)

別の注意:比較は、正規化されていない方向でも正常に機能しますが、内積を正規化しないままにすると、他の問題が発生する可能性があることに注意してください。

于 2011-07-04T21:14:11.573 に答える