2010-11-07 14 views
5

Tengo un programa OpenGL (escrito en Delphi) que permite al usuario dibujar un polígono. Quiero girarlo (girar) automáticamente alrededor de un eje (por ejemplo, Y asix) y obtener una forma 3D.OpenGL: ¿cómo laalizar una forma 2D en 3D?

¿Cómo puedo hacer esto?

Respuesta

4

Para simplificar, puede forzar al menos un punto para que se apoye en el eje de rotación. Puede hacer esto fácilmente agregando/restando el mismo valor a todos los valores x, y el mismo valor a todos los valores y, de los puntos en el polígono. Retendrá la forma original.

El resto no es realmente tan difícil. Elija un ángulo que sea bastante pequeño, digamos uno o dos grados, y resuelva las coordenadas de los vértices del polígono a medida que gira alrededor del eje. Luego solo une los puntos con triángulos y triángulos.

Para rotar un punto alrededor de un eje es básico Pitágoras. A 0 grados de rotación, tienes los puntos en sus coordenadas 2-d con un valor de 0 en la tercera dimensión.

Supongamos que los puntos están en X e Y y estamos girando alrededor de Y. La coordenada 'X' original representa la hipotenusa. En 1 grado de rotación, tenemos:

sin(1) = z/hypotenuse 
cos(1) = x/hypotenuse 

(asumiendo funciones basadas en grado trigonométricas)

Para girar un punto (x, y) por ángulo T alrededor del eje Y para producir un punto 3d (x 'y', z '):

y' = y 
x' = x * cos(T) 
z' = x * sin(T) 

Así que para cada punto en el borde de su polígono que producen un círculo de 360 ​​puntos centrados en el eje de rotación.

Ahora hacer una forma 3D, así:

  1. crear un GL 'fan triángulo' mediante el uso de su punto central y la primera matriz de puntos rotados
  2. para cada matriz sucesiva, cree una tira triángulo usando los puntos de la matriz y los puntos de la matriz anterior
  3. acabado mediante la creación de otro ventilador triángulo centrada en el punto central y el uso de los puntos en la última matriz

Uno Lo que hay que notar es que, por lo general, los tipos de funciones trigonométricas que he usado miden ángulos en radianes, y OpenGL usa grados. Para convertir grados a radianes, la fórmula es:

degrees = radians/pi * 180 
+0

¡Gracias por la respuesta! Fue simple y bien explicado. – Mahm00d

+0

Es un placer, @Flom – sje397

0

si lo que desea que gire, a continuación:

glRotatef(angle,0,1,0); 

girará alrededor del eje y. Si quieres un torno, entonces esto es mucho más complejo.

+0

Mi error. Por revolución me refiero a torno. Voy a editar la pregunta. – Mahm00d

1

Esencialmente, la estrategia es para barrer el perfil dado por el usuario alrededor del eje dado y generar una serie de tiras de triángulos que conectan las rebanadas adyacentes.

Suponga que el usuario ha dibujado el polígono en el plano XZ. Además, suponga que el usuario intenta barrer el eje Z (es decir, la línea X = 0) para generar el sólido de la revolución, y que un borde del polígono se encuentra en ese eje (puede generalizar más adelante una vez que tenga este caso simplificado trabajando).

Para una geometría lo suficientemente simple, puede tratar el perímetro del polígono como una función x = f (z), es decir, suponga que hay un único valor X para cada valor Z. Cuando vamos a 3D, esta función se convierte en r = f (z), es decir, el radio es único sobre la longitud del objeto.

Ahora, supongamos que queremos aproximar el sólido con M "rebanadas" abarcando cada una 2 * Pi/M radianes. Usaremos N "pilas" (muestras en la dimensión Z) también. Para cada sector, podemos construir una franja triangular que conecte los puntos en un sector (i) con los puntos del sector (i + 1). Aquí hay un código pseudo-ish que describe el proceso:

double dTheta = 2.0 * pi/M; 
double dZ = (zMax - zMin)/N; 

// Iterate over "slices" 
for (int i = 0; i < M; ++i) { 
    double theta = i * dTheta; 
    double theta_next = (i+1) * dTheta; 

    // Iterate over "stacks": 
    for (int j = 0; j <= N; ++j) { 
    double z = zMin + i * dZ; 

    // Get cross-sectional radius at this Z location from your 2D model (was the 
    // X coordinate in the 2D polygon): 
    double r = f(z); // See above definition 

    // Convert 2D to 3D by sweeping by angle represented by this slice: 
    double x = r * cos(theta); 
    double y = r * sin(theta); 

    // Get coordinates of next slice over so we can join them with a triangle strip: 
    double xNext = r * cos(theta_next); 
    double yNext = r * sin(theta_next); 

    // Add these two points to your triangle strip (heavy pseudocode): 
    strip.AddPoint(x, y, z); 
    strip.AddPoint(xNext, yNext, z); 
    } 
} 

Esa es la idea básica. Como dijo sje697, posiblemente necesitará agregar tapas para mantener la geometría cerrada (es decir, un objeto sólido, en lugar de un caparazón). Pero esto debería darte lo suficiente como para ponerte en marcha. Esto también se puede generalizar fácilmente a las formas toroidales (aunque en ese caso no tendrá una función uno a uno r = f (z)).

Cuestiones relacionadas