Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links
En este programa voy a graficar el movimiento de un proyectil en 3D usando
OpenGL, primero voy a plantear y resolver el sistema de ecuaciones diferenciales
del movimiento, donde V es la velocidad inicial de disparo, rho,theta
son los angulos de tiro, la unica fuerza exterior que actua es la aceleracion
de la gravedad.
Las ecuaciones son
condiciones iniciales del sistema
donde las componentes de V con relacion a los ejes de coordenadas son
intengrando dos veces
empleando las condiciones iniciales para t=0
luego la solucion queda
en el grafico, los puntos de la trayectoria estan en blanco, los ejes de coordenadas en amarillo, en rojo el vector que representa la direccion de tiro, los datos del tiro son:
#include <stdlib.h> #include <math.h> #include <stdio.h> #include <GL/glut.h> #define PI 3.141592654 #define g 9.8 float x_init, y_init, z_init; float rho, theta; float V; void Dibujar_Grid(GLfloat GridScale, GLfloat XSteps, GLfloat ZSteps) { GLfloat zExtent, xExtent; GLfloat xLocal, zLocal; int loopX, loopZ; glBegin( GL_LINES ); zExtent = GridScale*ZSteps; for(loopX = -XSteps; loopX <=XSteps; loopX++ ) { xLocal = GridScale*loopX; glVertex3f( xLocal, 0.0, -zExtent ); glVertex3f( xLocal, 0.0, zExtent ); } xExtent = GridScale * XSteps ; for(loopZ = -ZSteps; loopZ <= ZSteps; loopZ++ ) { zLocal = GridScale * loopZ; glVertex3f( -xExtent, 0.0, zLocal ); glVertex3f( xExtent, 0.0, zLocal ); } glEnd(); } void Dibujar_VectorTiro(void) { float x, y, z; float l; l=1.0; x=l*sin(rho)*sin(theta); y=l*cos(rho); z=l*sin(rho)*cos(theta); x_init=x; y_init=y; z_init=z; glBegin(GL_LINES); glVertex3f(0.0, 0.0, 0.0); glVertex3f( x, y, z); glEnd(); } void Dibujar_Ejes(void) { glBegin(GL_LINES); //eje X glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); //eje Y glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); //eje Z glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glEnd(); } void Dibujar_Trayectoria(void) { float x_pos, y_pos, z_pos; float Vx, Vy, Vz; float t, dt; x_pos=x_init; y_pos=y_init; z_pos=z_init; Vx=V*sin(rho)*sin(theta); Vy=V*cos(rho); Vz=V*sin(rho)*cos(theta); t=0.0; dt=0.02; glBegin(GL_POINTS); while (y_pos>=0) { x_pos = Vx*t + x_init; y_pos = Vy*t-0.5*g*t*t + y_init; z_pos = Vz*t + z_init; glVertex3f(x_pos, y_pos, z_pos); t=t+dt; }; glEnd(); } void iniciar(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glPointSize(2.0); rho=PI/4.0; theta=PI/8.0; V=10.0; } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); gluLookAt(2.0, 2.0, -3.0, 0.0, 0.0, 5.0, 0.0, 1.0, 0.0); glLineWidth(1.0); glColor3f(0.5, 0.5, 0.5); Dibujar_Grid(1.0, 20.0, 20.0); glColor3f (1.0, 1.0, 0.0); Dibujar_Ejes(); glLineWidth(2.0); glColor3f (1.0, 0.0, 0.0); Dibujar_VectorTiro(); glColor3f (1.0, 1.0, 1.0); Dibujar_Trayectoria(); glPopMatrix(); glFlush(); } void reshape(int w, int h) { if (!h) return; glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(400, 400); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutCreateWindow("Tiro en 3D"); iniciar(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } |
valcoey@hotmail.com
Ramiro
Buenos Aires, Argentina, 2002
Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links