2011-10-09 6 views
0

Plus une question de maths qu'une question de programmation, mais j'ai besoin de coder la rotation de la caméra et je n'ai aucune idée de comment. Les maths sont un peu à abstraire pour moi de le faire à l'improviste. La rotation de la caméra est faite avec des quaternions, tout ce que je veux vraiment, c'est un échantillon à étudier ou juste un article sur le sujet mais je ne trouve rien.Algorithme de rotation de caméra

+0

être plus précis. Quel genre de rotation? – BlackBear

+0

ouais, bonne question. Juste très simple, une caméra volante pour explorer une scène c'est tout. J'ai déjà codé le mouvement/zoom. Il ne devrait pas être plus alors quand votre souris se lève l'appareil photo se lève et la souris se déplace à droite la came suit – Tim

+0

Vous "ne pouvez rien trouver" sur les quaternions et les transformations 3d en général? Désolé, mais je ne peux pas croire. Il y a énormément de matériaux et chaque livre de base sur l'infographie ou un sujet similaire devrait traiter cela comme un seul si les premiers chapitres. Cependant, si vous n'êtes pas familiarisé avec le simple vecteur et l'algèbre matricielle, la rotation d'une caméra est votre moindre problème. –

Répondre

1

Voici quelque chose que j'ai écrit dans opengl. l'algorithme de base devrait être le même dans toutes les langues. les choses dont vous avez besoin sont:

le vecteur d'unité de longueur (où est valorisé si vous êtes à la recherche au centre): (UPX, UPY, upz)

origine

(l'endroit où vous êtes à la recherche) : (bœuf, oy, oz)

de position de la caméra (où votre appareil photo est): (cx, cy, cz)

assumer "del" est le montant que vous souhaitez déplacer, et que

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

après cela, vous pouvez calculer le vecteur "forward". c'est le vecteur qui est la longueur de l'unité et les points de vous au centre via:

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

vous pouvez calculer l'unité « gauche » vecteur, qui est le vecteur pointant vers la gauche de la longueur de l'unité si vous sont à la recherche au centre:

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

vous pouvez alors écrire les routines suivantes (chaque original '//' gauche justifié signifie une nouvelle 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; 
0

Here C'est une bonne idée à ce sujet. C'est XNA (C#), mais le code est facile à comprendre.

+0

Merci, je vais regarder, il semble prometteur – Tim

+0

@Dasdasd: oui, c'est un bon tut. J'ai aussi appris sur ça – BlackBear

Questions connexes