Матрица вращения 3D приводит к тому, что изображение повторяется до бесконечности

Основываясь на некотором исследовании трехмерных матриц вращения, я сделал этот jsfiddle, который сам по себе не работает. , потому что вы не можете использовать ctx.getImageData () для внешних видео или изображений (но если вы хотите попробовать тот же код на локальном источнике видео, он должен работать нормально).

Большая часть 3D-магии происходит при умножении двух матриц. Для каждой точки изображения координаты xyz умножаются на матрицу вращения в функции rotatePoint, которая преобразует точку xyz на ось вращения из начала координат p в направлении единичного вектора u. на "тета" радианы.

function rotatePoint(xyz,p,u,rho,phi){
return new Vector(
    ((p.x*(u.y*u.y+u.z*u.z)-u.x*(p.y*u.y+p.z*u.z-u.x*xyz.x-u.y*xyz.y-u.z*xyz.z))*(1-rho)+xyz.x*rho+(-p.z*u.y+p.y*u.z-u.z*xyz.y+u.y*xyz.z)*phi)|0,
    ((p.y*(u.x*u.x+u.z*u.z)-u.y*(p.x*u.x+p.z*u.z-u.x*xyz.x-u.y*xyz.y-u.z*xyz.z))*(1-rho)+xyz.y*rho+( p.z*u.x-p.x*u.z+u.z*xyz.x-u.x*xyz.z)*phi)|0,
    ((p.z*(u.x*u.x+u.y*u.y)-u.z*(p.x*u.x+p.y*u.y-u.x*xyz.x-u.y*xyz.y-u.z*xyz.z))*(1-rho)+xyz.z*rho+(-p.y*u.x+p.x*u.y-u.y*xyz.x+u.x*xyz.y)*phi)|0)
}

Где «ро» - это грех (тета), а «фи» - это соз (тета), а тета - это угол поворота.

Наконец, точка умножается на матрицу перспективы в следующей функции, которая преобразует точку из мировых координат в координаты экрана.

function perspective(xyz){
    return {
    x : ((this.camera.e.z*(xyz.x-this.camera.e.x))/(this.camera.e.z+xyz.z)+this.camera.e.x)|0,
    y : ((this.camera.e.z*(xyz.y-this.camera.e.y))/(this.camera.e.z+xyz.z)+this.camera.e.y)|0
    }
}

Теперь все это по большей части работает нормально. Но по какой-то причине трехмерное вращение приводит к тому, что изображение уходит в бесконечность вдоль оси вращения. Вот пример скриншота:

введите описание изображения здесь

Кто-нибудь знает, почему это происходит?


person jonbrennecke    schedule 05.01.2014    source источник


Ответы (1)


Ваша функция визуализации обновляет координату Z вашего изображения в каждом кадре.
Она заставляет визуализированное изображение перемещаться от кадра к кадру. Вы можете заметить это в начале, когда изображение поворачивается до тех пор, пока ориентация изображения не стабилизируется.

Кроме того, алгоритм использует саму поверхность рендеринга в качестве источника, поэтому, если он работает достаточно быстро, он будет обрабатывать преобразованное изображение рекурсивно, что приведет к эффекту «перспективы до бесконечности».

Наконец, он не проверяет переполнение координат пространства изображения, что приводит к переносу, когда граница изображения выходит за пределы следующей строки сканирования.

Формула вращения кажется правильной (она действительно вращает точку вдоль указанной оси), но способ ее использования довольно странный.
Она действительно поворачивает изображение вдоль оси Y, как обратимая доска, переворачивающаяся на петлях, а затем соответственно обновляет координату Z изображения. В конечном итоге трехмерное изображение растягивается вдоль исходной оси Z.
В сочетании с постепенным изменением значений Z это, кажется, сходится к некоторому фиксированному растяжению / повороту, применяемому к исходному изображению, вычисление которого выходит за рамки моих математических расчетов .

Исходный объект камеры, кажется, был отброшен (используется только таинственный вектор «е», как своего рода помощник для проекции перспективы).

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

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

См. Рабочий пример здесь. Требуется браузер HTML5 с поддержкой mp4. Протестировано на последней версии FireFox.
(это не JSfiddle, поскольку безопасность изображений не позволяет ничего видеть, но код находится внутри страницы).

person kuroi neko    schedule 06.01.2014
comment
Спасибо. Было весело писать код. Надеюсь, вы не возражали против моего выбора видео :) - person kuroi neko; 07.01.2014