2010-07-08 17 views
9

Cuando tengo un QUAD en una posición determinada, ¿cómo puedo rotarlo de manera que su punto normal sea hacia un punto dado? Imagina que los bloques de colores son solo cuatriciclos rectangulares, entonces esta imagen muestra un poco lo que quiero decir. Los cuádriceps están orientados de tal manera que apuntan hacia el centro de la esfera.C++/openGL: Girando un QUAD hacia un punto usando quaternions

alt text http://emrahgunduz.com/wp-content/uploads/2009/01/material_id_gui-600x364.jpg

Tal vez esta segunda imagen muestra un poco más de lo que estoy tratando de hacer: alt text http://img689.imageshack.us/img689/3130/screenshot20100708at555.png

estoy usando OpenGL/C++ (y de la librería Eigen). Y tengo el código para dibujar un quad simple:

#include "ofMain.h" 
#include "Quad.h" 
Quad::Quad(Vector3f oPosition):position(oPosition) { 
} 

void Quad::update() { 
} 

void Quad::draw() { 
    float size = 1.3; 
    glColor3f(1.0f, 0.0f, 0.6f); 
    glPushMatrix(); 
     glTranslatef(position.x(), position.y(), position.z()); 
     glScalef(size, size,size); 
     glBegin(GL_QUADS); 
      glVertex3f(0,0,0); 
      glVertex3f(1,0,0); 
      glVertex3f(1,1,0); 
      glVertex3f(0,1,0); 
     glEnd(); 
    glPopMatrix(); 
} 

actualización 17-07 Estimado lector,

acaba de recibir un poco más con la rotación de los quads. Estoy posicionar un par de quads al azar y luego girarlas hacia un look_at Vector3f utilizando este código usando las descripciones de las respuestas siguientes:

void Quad::draw() { 
    float size = 0.5; 
    glColor3f(1.0f, 0.0f, 0.6f); 
    glPushMatrix(); 
     Vector3f center = look_at - position; 
     Vector3f center_norm = center.normalized(); 
     float r_angle = acos(center_norm.dot(normal)); 
     Vector3f axis = normal.normalized().cross(center_norm); 

     glPointSize(8); 
     glLineWidth(4.0f); 

     // draw the center point 
     glColor3f(1.0f, 0.0f, 0.0f); 
     glBegin(GL_POINTS); 
      glVertex3fv(look_at.data()); 
     glEnd(); 

     // draw the quad 
     glColor4f(0.0f, 0.0f, 0.0f, 0.85f); 
     glTranslatef(position.x(), position.y(), position.z()); 
     glRotatef(r_angle * RAD_TO_DEG, axis.x(), axis.y(), axis.z()); 
     glScalef(size, size,size); 
     glBegin(GL_QUADS); 
      glVertex3f(-0.5,-0.5,0); 
      glVertex3f(0.5,-0.5,0); 
      glVertex3f(0.5,0.5,0); 
      glVertex3f(-0.5,0.5,0); 
     glEnd(); 

    glPopMatrix(); 
} 

El resultado es el siguiente: alt text http://img688.imageshack.us/img688/711/3drotatedquads.png

Como puedo ver que estoy casi allí, aunque la rotación de los cuádriceps sigue siendo un poco "extraña". Si ves la imagen a continuación con los cuadrantes de colores, puedes ver claramente la diferencia en la rotación. ¿Cómo puedo rotar el quad de tal manera que obtenga el mismo resultado que la esfera de color de abajo?

+0

+1: Porque me encantan las imágenes en 3D :) – ereOn

+0

Estos enlaces a las imágenes están todos rotos. –

Respuesta

1

eje de rotación = Normalizar (productos cruzados (currentNormal, desiredNormal)) Ángulo de

Rotación = Acos (dotProduct (normalizar (currentNormal), normalizar (desiredNormal)).

Usted puede construir o bien matriz de rotación o cuaternión desde el eje y el ángulo. fórmula exacta se puede encontrar en cualquier recurso sobre cuaterniones.

Es posible que tenga que voltear ángulo o eje en función de si se gira normal alrededor de su base o alrededor de su punta.

También el recurso THIS parece tener suficiente información sobre cuaterniones, rotaciones y espacio 3d en general.

+0

Hola SigTerm, pero ¿cómo puedo resolver esto cuando no conozco mi actualNormal? Solo obtuve el código que pegué (la clase 'Quad'). – pollux

+1

Para un quad abcd normal se puede encontrar usando cross product = normalize (cross (c-a, d-b)) o normalize (Crossproduct (b-a, c-a)). Se pueden usar dos vectores no paralelos de quad para hacer perpendicular. En su ejemplo, normal es (0, 0, 1) o (0, 0, -1). (depende de si los cuádriceps usan el mismo orden de devanado, unilateral o de doble cara, etc.). – SigTerm

+0

SigTerm, ¿qué quiere decir con girar alrededor de su "base" o "punta"? ¿Podría esto causar el resultado que tengo ahora (ver los quads negros arriba) – pollux

0

Si "en una determinada posición" significa que usted sabe que su corriente normal, que aquí está la cosa:

  1. producto escalar de una antigua y nueva normalidad es un coseno de un ángulo entre ellos.
  2. Su producto cruzado es un eje alrededor del cual debe realizar la rotación deseada
  3. La construcción del cuaternión de rotación del eje y el ángulo dados está bien documentada y es una característica básica.
  4. La rotación del quad en sí es complicada y depende de cómo exactamente desea que se gire.
Cuestiones relacionadas