opengl - rotacion - Encontrar ángulos de rotación entre puntos 3d
rotacion de puntos en el plano cartesiano (3)
Estoy escribiendo un programa que dibujará un sólido a lo largo de la curva de una spline. Estoy usando Visual Studio 2005 y escribiendo en C ++ para OpenGL. Estoy usando FLTK para abrir mis ventanas (kit de herramientas rápido y ligero).
Actualmente tengo un algoritmo que dibujará una línea cúbica cardinal, dado un conjunto de puntos de control, dividiendo los intervalos entre los puntos en subintervalos y dibujando alineaciones entre estos puntos secundarios. El número de subintervalos es variable.
El código de dibujo lineal funciona maravillosamente y básicamente funciona de la siguiente manera: genero un conjunto de puntos a lo largo de la curva spline usando la ecuación spline y los almaceno en una matriz (como una estructura de datos especial llamada Pnt3f, donde las coordenadas son 3 flotantes y hay algunas funciones prácticas como distancia, longitud, punto y producto cruzado). Luego tengo un solo bucle que itera a través de la matriz de puntos y los dibuja de la siguiente manera:
glBegin(GL_LINE_STRIP);
for(pt = 0; pt<=numsubsegements ; ++pt) {
glVertex3fv(pt.v());
}
glEnd();
Como se dijo, este código funciona muy bien. Ahora lo que quiero hacer es, en lugar de dibujar una línea, quiero extruir un sólido. Mi exploración actual está usando un cuádrice "cilindro" para crear un tubo a lo largo de la línea. Esto es un poco más complicado, ya que tengo que orientar OpenGL en la dirección en que quiero dibujar el cilindro. Mi idea es hacer esto:
Psuedocode:
Push the current matrix,
translate to the first control point
rotate to face the next point
draw a cylinder (length = distance between the points)
Pop the matrix
repeat
Mi problema es obtener los ángulos entre los puntos. Solo necesito guiñada y cabeceo, el balanceo no es importante. Sé que tomar el arco-coseno del producto escalar de los dos puntos dividido por la magnitud de ambos puntos, devolverá el ángulo entre ellos, pero esto no es algo que pueda alimentar a OpenGL para rotar. Intenté hacer esto en 2d, usando el plano XZ para obtener la rotación xy hacer los vectores de puntos desde el origen, pero no devuelve el ángulo correcto.
Mi enfoque actual es mucho más simple. Para cada plano de rotación (X e Y), encuentre el ángulo por:
arco-coseno ((diferencia en ''valores x'') / distancia entre los puntos)
el valor "x" depende de cómo configures tu avión, aunque para mis cálculos siempre uso el mundo x.
Salvo algunas cuestiones que hacen que dibuje en el cuadrante correcto que aún no he resuelto, quiero obtener consejos para ver si esta fue una buena implementación, o para ver si alguien conocía una mejor manera.
¿Has considerado gluLookAt
? Ponga su punto de control como el punto del ojo, el siguiente punto como el punto de referencia, y haga que el vector ascendente sea perpendicular a la diferencia entre los dos.
Algunas notas:
en primer lugar, esto:
for(pt = 0; pt<=numsubsegements ; ++pt) {
glBegin(GL_LINE_STRIP);
glVertex3fv(pt.v());
}
glEnd();
no es una buena forma de dibujar nada. DEBES tener un glEND () para cada glBegin (). es probable que desee sacar el glBegin () del ciclo. el hecho de que esto funcione es pura suerte.
segunda cosa
Mi exploración actual está usando un cuádrice "cilindro" para crear un tubo a lo largo de la línea
Esto no funcionará como esperabas. el cuadriculado ''cilindro'' tiene una base superior plana y una base inferior plana. Incluso si tiene éxito en hacer las rotaciones correctas de acuerdo con la spline, los bordes de las tapas planas saldrán del volumen de su tubo previsto y no será liso. Puedes probarlo en 2D con solo un bolígrafo y un papel. Trate de dibujar un tubo liso usando tubos más cortos con bases planas. Esto es imposible.
En tercer lugar, a su pregunta real, la herramienta definitiva para tales rotaciones son los cuaterniones . Es un poco complejo de explicar en este ámbito, pero puede encontrar abundante información en cualquier lugar que busque.
Si hubiera utilizado QT en lugar de FLTK, también podría haber usado libQGLViewer . Tiene una clase Quaternion integrada que le ahorrará la implementación. Si todavía tiene una opción, le recomiendo que se mude a QT.
Tiene razón al formar dos vectores de los tres puntos en dos segmentos de línea adyacentes y luego usar el arcocoseno del producto de puntos para obtener el ángulo entre ellos. Para utilizar este ángulo, necesita determinar el eje alrededor del cual debería ocurrir la rotación. Tome el producto cruzado de los mismos dos vectores para obtener este eje. A continuación, puede construir una matriz de transformación utilizando este ángulo de eje o pasarla como parámetros a glRotate .