Camera Rotation Algorithm

亡梦爱人 提交于 2020-12-16 04:54:36

问题


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.


回答1:


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;


来源:https://stackoverflow.com/questions/7703262/camera-rotation-algorithm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!