Выбор соответствующей плоскости ограничительной рамки до пересечения плоскости луча - PullRequest
1 голос
/ 05 июля 2011

Я отслеживаю объекты, для которых мне нужно проверить, находятся ли они внутри или снаружи куба / ограничительной рамки.Если они находятся снаружи, я делаю пересечение плоскости луча, чтобы вычислить точку на одной из плоскостей куба.Луч начинается в центре коробки и указывает на объект.Плоскость является одной из 6, составляющих куб.

Чего я хотел бы избежать, так это того, что я постоянно проверяю пересечение плоскости луча на каждой из 6 плоскостей.Поэтому я подумал, что должен быть умным и сначала рассчитать скалярное произведение между каждой из нормалей плоскости и луча.Затем выберите тот, который имеет наименьший угол (ближайший к 1).

Это работает только наполовину.Есть места, когда объект выровнен с одной из плоскостей, где моя функция выбирает неправильную плоскость.Хотя в большинстве случаев это работает, и мне интересно, почему это так.Я полагаю, что с моим подходом должно быть что-то в корне не так.

Вот мои определенные плоскости, у каждой из которых есть метка.0,0,0 системы координат - это один угол куба.

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

Что мне здесь не хватает?

Полагаю, я мог бы просто провести тест на столкновение на каждой плоскости, а затем выбрать точку, ближайшую к центру куба, но это кажется пустой тратой.

1 Ответ

1 голос
/ 05 июля 2011

Ваш аргумент будет в порядке, если куб действительно был кубом, то есть все измерения одинаковы (и только для случая, когда он находится в центре правильного многогранника).Но, похоже, у вас разные размеры для каждой из осей.

Если одна длина довольно мала (представьте себе очень тонкую рамку), независимо от того, в каком направлении вы смотрите почти в любом случае, вы попадете в тебольшие плоскости и почти никогда не тонкие стороны.

Вы можете компенсировать это, если вы масштабируете свое направление по точной длине коробки.Т.е. вместо direction вы используете direction/(cubeSize.x,cubeSize.y,cubeSize.z), где деление выполняется по координате.

Еще одно замечание: обратите внимание, что сравнение работает нормально, также с ненормализованным направлением, но вы можете столкнуться с проблемами в другом, если вы продолжитеваш точечный продукт ненормализован.

...