相机旋转算法

发布于 2024-12-08 18:50:14 字数 120 浏览 0 评论 0原文

更多的是一个数学问题,而不是一个编程问题,但我需要编写相机旋转代码,但我不知道如何做。对于我来说,突然做的数学有点抽象。 相机的旋转是用四元数完成的,我真正想要的是一个研究样本或者只是一篇关于该主题的文章,但我找不到任何东西。

More a maths question then a programming one, but I need to code camera rotation and I have no idea how. The maths are a bit to abstract for me to do out of the blue.
The camera's rotation is done with quaternions, all I really want is a sample to study or just an article about the subject but I can't find anything.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一梦浮鱼 2024-12-15 18:50:15

这是我用 opengl 写的东西。任何语言的基本算法都应该是相同的。你需要的东西是:

单位长度的向上向量(如果你看着中心,则向上定义):(upx,upy,upz)

原点(你正在看的地方):(ox,oy,oz)

相机位置(你的相机所在的位置):(cx,cy,cz)

假设“del”是你想要移动的量,

norma() = (ox-cx, oy-cy, oz-cz)/sqrt( (ox-cx) * (ox-cx) + (oy-cy) * (oy-cy) + (oz-cz) * (oz-cz) )

之后,你可以计算“前向”向量。也就是说,单位长度的向量通过以下方式从你指向中心:

(fox, foy, foz) = (ox-cx, oy-cy, oz-cz)/norma();

然后你可以计算单位“左”向量,即如果你看着中心,则指向单位长度左侧的向量

lx = foz*upy-foy*upz;
ly = fox*upz-foz*upx;
lz = foy*upx-fox*upy;

:然后可以编写以下例程(每个原始的“//”左对齐表示一个新例程)

// move camera forward
        cx = cx + del*fox;
        cy = cy + del*foy;
        cz = cz + del*foz;

// move camera backward
        cx = cx - del*fox;
        cy = cy - del*foy;
        cz = cz - del*foz;

// rotate figure right
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx + del*lx;
        cy = cy + del*ly;
        cz = cz + del*lz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );


// rotate left
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx - del*lx;
        cy = cy - del*ly;
        cz = cz - del*lz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );

// rotate figure up
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx + del*upx;
        cy = cy + del*upy;
        cz = cz + del*upz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        upx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upy = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );



// rotate figure down
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx - del*upx;
        cy = cy - del*upy;
        cz = cz - del*upz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        upx = (cx0-cx)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upy = (cy0-cy)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upz = (cz0-cz)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );



// move fig down
        cx = cx + del*upx;
        cy = cy + del*upy;
        cz = cz + del*upz;

        ox = ox + del*upx;
        oy = oy + del*upy;
        oz = oz + del*upz;

// move fig up
        cx = cx - del*upx;
        cy = cy - del*upy;
        cz = cz - del*upz;

        ox = ox - del*upx;
        oy = oy - del*upy;
        oz = oz - del*upz;

// move fig left
        cx = cx + del*rx;
        cy = cy + del*ry;
        cz = cz + del*rz;

        ox = ox + del*rx;
        oy = oy + del*ry;
        oz = oz + del*rz;

// move fig right
        cx = cx - del*rx;
        cy = cy - del*ry;
        cz = cz - del*rz;

        ox = ox - del*rx;
        oy = oy - del*ry;
        oz = oz - del*rz;

here is something i wrote in opengl. the basic algorithm should be the same in any language. the things you need are:

the up vector of unit length (where up is defined if you are looking at the center): (upx, upy, upz)

origin (the place you are looking at): (ox,oy,oz)

camera position (where your camera is): (cx, cy, cz)

assume "del" is the amount you want to move, and that

norma() = (ox-cx, oy-cy, oz-cz)/sqrt( (ox-cx) * (ox-cx) + (oy-cy) * (oy-cy) + (oz-cz) * (oz-cz) )

after that, you can calculate the "forward" vector. that is, the vector which is unit length and points from you to the center via:

(fox, foy, foz) = (ox-cx, oy-cy, oz-cz)/norma();

you can then calculate the unit "left" vector, that is, the vector pointing to the left of unit length if you are looking at the center:

lx = foz*upy-foy*upz;
ly = fox*upz-foz*upx;
lz = foy*upx-fox*upy;

you can then write the following routines (each original '//' justified left signifies a new routine)

// move camera forward
        cx = cx + del*fox;
        cy = cy + del*foy;
        cz = cz + del*foz;

// move camera backward
        cx = cx - del*fox;
        cy = cy - del*foy;
        cz = cz - del*foz;

// rotate figure right
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx + del*lx;
        cy = cy + del*ly;
        cz = cz + del*lz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );


// rotate left
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx - del*lx;
        cy = cy - del*ly;
        cz = cz - del*lz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "left" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        lx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        ly = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        lz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );

// rotate figure up
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx + del*upx;
        cy = cy + del*upy;
        cz = cz + del*upz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        upx = (cx-cx0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upy = (cy-cy0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upz = (cz-cz0)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );



// rotate figure down
        cx0 = cx; // initial position
        cy0 = cy;
        cz0 = cz;

        R1 = norma(); // initial distance
        cx = cx - del*upx;
        cy = cy - del*upy;
        cz = cz - del*upz;
        R2 = norma(); // new distance after moving in up direction
        cx = cx + (R2-R1)*fox;
        cy = cy + (R2-R1)*foy;
        cz = cz + (R2-R1)*foz; // move towards center so the original distance is the same

        // new "up" vector should be (cx-cx0, cy-cy0, cz-cz0) but normalized
        upx = (cx0-cx)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upy = (cy0-cy)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );
        upz = (cz0-cz)/sqrt( (cx-cx0)*(cx-cx0) + (cy-cy0)*(cy-cy0) + (cz-cz0)*(cz-cz0) );



// move fig down
        cx = cx + del*upx;
        cy = cy + del*upy;
        cz = cz + del*upz;

        ox = ox + del*upx;
        oy = oy + del*upy;
        oz = oz + del*upz;

// move fig up
        cx = cx - del*upx;
        cy = cy - del*upy;
        cz = cz - del*upz;

        ox = ox - del*upx;
        oy = oy - del*upy;
        oz = oz - del*upz;

// move fig left
        cx = cx + del*rx;
        cy = cy + del*ry;
        cz = cz + del*rz;

        ox = ox + del*rx;
        oy = oy + del*ry;
        oz = oz + del*rz;

// move fig right
        cx = cx - del*rx;
        cy = cy - del*ry;
        cz = cz - del*rz;

        ox = ox - del*rx;
        oy = oy - del*ry;
        oz = oz - del*rz;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文