Основываясь на некотором исследовании трехмерных матриц вращения, я сделал этот 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
}
}
Теперь все это по большей части работает нормально. Но по какой-то причине трехмерное вращение приводит к тому, что изображение уходит в бесконечность вдоль оси вращения. Вот пример скриншота:
Кто-нибудь знает, почему это происходит?