Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SaulH en 26 Marzo 2023, 05:12 am



Título: Disparo parabolico en c++ con la libreria GLUT
Publicado por: SaulH en 26 Marzo 2023, 05:12 am
necesito su ayuda o sugerencias para resolver el siguiente problema: crear una funcion proyectil la cual mediante el teclado se pueda controlar su potencia de disparo. Lo intente hacer pero no me salio,  no se como hacer los calculos e implementarlos en el codigo. Este el codigo que llevo hasta ahora:

Librerias

Código:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <gl\glut.h>
using namespace std;

Variables globales

Código:
float g = 9.8, v = 12, ang = 45; 

Funcion dibujar

Código:
void Dibujar(){
glClear(GL_COLOR_BUFFER_BIT); //borra la pantalla grafica como un cls

glColor3f(1.0, 0.0, 0.0);

crea los ejes x e y

Código:
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(30.0, 0.0, 0.0);
glVertex3f(0.0, 30.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();

bloque de código dibuja una trayectoria de puntos verdes en la pantalla

Código:
glBegin(GL_POINTS); //indica que se dibujarán puntos
float rad = ang/57.3; //convierte el ángulo ang (en grados) a radianes.
 for(float x = 0; x <= 1000; x = x + 0.2){
    float y = tan(rad)*x-(g/(2*v*v*cos(rad)*cos(rad)))*x*x; //calcula la posición
 //vertical y correspondiente a la posición horizontal x en la trayectoria, utilizando
 //la fórmula de la trayectoria de un proyectil
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(x, y, 0.0);
    if(y<0) {break;} //detiene el bucle si la posición vertical y es negativa, lo que
    //significa que el proyectil ha caído al suelo.
    }
glEnd();

glFlush();
}

función que establece la perspectiva y la posición de la cámara para que se pueda ver la escena correctamente en la ventana de visualización.

Código:
void CambiarTamano(int ancho, int alto){
if(alto == 0) alto = 1;
float razon = 1.0*ancho/alto;
glMatrixMode(GL_PROJECTION); //activaq el modo de proyeccion
glLoadIdentity(); //carga la imagen
glViewport(0, 0, ancho, alto);
gluPerspective(45, razon, 1, 1000); //cambia la perspectiva de acuerdo a la razon
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(10.0, 7.0, 20.0, //donde esta la camara
      10.0, 7.0, 0.0, //hacia donde esta viendo
      0.0, 1.0, 0.0); //cual es el eje hacia arriba
}

función que se llama cuando se presiona una tecla especial del teclado mientras se está ejecutando el programa

Código:
void Flechas(int key, int x, int y){
switch(key){
case GLUT_KEY_UP: ang +=1; Dibujar(); break;
case GLUT_KEY_DOWN: ang -=1; Dibujar(); break;
case GLUT_KEY_RIGHT: v +=1; Dibujar(); break;
case GLUT_KEY_LEFT: v -=1; Dibujar(); break;
}
}

Se inicia la biblioteca GLUT (glutInit) para configurar la ventana, los modos de visualización, la posición y el tamaño. Después, se registran las funciones de control de eventos con GLUT (glutSpecialFunc, glutDisplayFunc, glutReshapeFunc). Por último, se llama a glutMainLoop para iniciar el bucle de eventos de GLUT y mantener la ventana abierta hasta que el usuario la cierre.

Código:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(30, 30);
glutInitWindowSize(1000, 600);
glutCreateWindow("Prueba");
glutSpecialFunc(Flechas);
glutDisplayFunc(Dibujar);
glutReshapeFunc(CambiarTamano);
glutMainLoop();

return 0;
}




Título: Re: Disparo parabolico en c++ con la libreria GLUT
Publicado por: Lieutenant McFarley en 28 Marzo 2023, 10:18 am
Desconozco el funcionamiento de la librería GLUT por lo que solo comentaré algo sobre el tiro parabólico y de pasada sobre el tamaño de la ventana gráfica y el posible retardo de la representación en pantalla.
He dado un vistazo a las ecuaciones del tiro parabólico y me parece que, en principo, están bien, aunque a mi me parece que sería más cómodo y eficiente trabajar con las ecuaciones paramétricas con x, y como función del tiempo y g, rad y v constantes:
x = v*cos(rad)*t
y = v*sen(rad)*t - 1/2*g*t*t
El bucle con 0<=x<1000 (supongo que metros) parece arbitrario; dependerá del los valores ang y v que sea más o menos. Por ejemplo en tu caso (45º y 12 m/s) el x(max) está en torno a 14 m, e y(max) en torno a 3.7  m, si no he hecho mal los cálculos. Pero por ejemplo con un tirachinas y apuntando casi en vertical (ang = 85º y v = 27 m/s <-> 100 km/h) son x(max) = 13 m e y(max) = 37 m. Y para un cañón de tanque con tiro casi rasante (v = 150 m/2 y ang = 2º) donde se tendría x(max) = 160 m e y(max) = 1.4 m.
Entonces poner una distancia máxima de 1.000 m y forzar a divisiones de 20 cm me parece arbitrario. Veo mucho más lógico calcular el t(max) para cada caso; con ang, v y g constantes, el t(max) se despeja de la ecuación de y para y = 0. Es una ecuación de 2º grado en t con dos valores: uno es, obviamente para t = 0, y el otro será el valor de t cuando vuelva a ser y = 0. Y ahora tomar el bucle for valores de t dividos en cierto número de intervalos (eso ya verás tu cuantos) y calcular parejas de valores x, y para representar.
Y esto va relacionado con el tamaño de la pantalla de representación gráfica. Coo ya he dicho desconozco como funciona GLUT y por tanto no sé si en el código que has puesto se dimensiona de alguna manera el tamaño, pero evidentemente la calidad de la representación no puede ser igual si pretendes representar el tiro del cañón (160m, 1.4 m) en una ventana del tamaño de tu ejemplo (14 m, 3.7 m). Repito que no sé si dimensionas el tamaño de la ventana en relación con (ang, v) que, asu vez delimita (x(max), y(max)). Es solo una consideración.
Y por último está la cuestión del retardo. No sé que tan rápido calcula representa tu programa, pero pudiera ser que sea tan rápido que no da tiempo a verlo y, a lo mejor, convendría intercalar un bucle de retardo entre punto y punto.
Nada más, como digo son algunas consideraciones de oreden general que no sé si te serán de ayuda, independientemente de si he hecho bien los números, que ya tengo un poco oxidado el cálculo manual (o con hoja de cálculo) y las ecuaciones.