Orbite Y dégringie de haut en bas à mesure que Mousey change dans le traitement IDE
-
29-10-2019 - |
Question
Remarque: c'est dans l'IDE de traitement
J'essaie de faire tomber sphérique et je l'ai presque. C'est ce que j'ai jusqu'à présent:
float cameraTheta, cameraPhi, cameraRadius; //camera position in spherical coordinates
float camx, camy, camz;
void setup() {
size(500, 500, P3D);
background(255);
cameraRadius = 200.0f;
cameraTheta = 2.80;
cameraPhi = 2.0;
recomputeOrientation();
}
void draw() {
background(255);
lights();
mouseMotion();
camera(camx, camy, camz, 0, 0, 0, 0, -1, 0);
sphereDetail(10);
sphere(25);
}
void mouseMotion()
{
if (mousePressed) {
cameraTheta += (mouseX - pmouseX)*0.05;
cameraPhi += (mouseY - pmouseY)*0.05;
}
recomputeOrientation(); //update camera (x,y,z) based on (radius,theta,phi)
}
void recomputeOrientation()
{
camx = cameraRadius * sin(cameraTheta)*sin(cameraPhi);
camz = cameraRadius * -cos(cameraTheta)*sin(cameraPhi);
camy = cameraRadius * -cos(cameraPhi);
redraw();
}
La rotation X fonctionne très bien, mais la rotation y est en quelque de haut en arrière dans l'autre sens lorsque la souris se déplace. Quelqu'un peut-il m'aider à comprendre cela?
La solution
Le problème a à voir avec le vecteur vers le haut pour la caméra. Si vous imaginez tenir la caméra et la rapprocher de plus en plus du poteau de la sphère, comment tenez-vous la caméra lorsque vous passez devant le poteau? Le traitement sait quoi faire à cause du laver argument du fonction de caméra.
Dans votre code actuel, le laver est toujours -1, ce qui signifie que lorsque la caméra s'offre elle-même, elle utilisera toujours le vecteur <0, -1, 0> Comme sa référence pour en haut. Vous devez changer cela pour que lorsqu'il arrive au poteau de la sphère, il retourne à l'envers.
boolean flip = false;
...
void draw() {
...
camera(camx, camy, camz, 0, 0, 0, 0, flip ? 1.0 : -1.0, 0);
...
}
void mouseMotion()
{
if (mousePressed) {
cameraTheta += (mouseX - pmouseX) * 0.05;
if (cameraTheta < 0) cameraTheta += 2 * PI;
else if (cameraTheta >= 2 * PI) cameraTheta -= 2 * PI;
if (flip)
cameraPhi += (mouseY - pmouseY) * 0.05;
else
cameraPhi -= (mouseY - pmouseY) * 0.05;
if (cameraPhi >= PI) {
cameraPhi = PI - 0.01;
cameraTheta += PI;
flip = !flip;
}
else if (cameraPhi <= 0) {
cameraPhi = 0.01;
cameraTheta -= PI;
flip = !flip;
}
}
recomputeOrientation();
}
Choses notables:
- J'ai ajouté du code pour garder cameratheta dans la gamme [0, 2 * pi) et cameraphi dans la plage [0,01, Pi - 0,01). Mathématiquement, cameraphi devrait être dans la gamme [0, pi), mais cela provoque un scintillement aux pôles. Pour les mathématiques derrière cela, vérifiez ici.
- cameraphi est incrémenté inversement lorsque retourner est vrai.