sábado, 15 de junio de 2013

Alcance del tiro parabólico


Este programa sigue en la misma línea del anterior. Se trata de resolver problemas tipo y típicos mediante un programa que espera unos datos numéricos introducidos por teclado. La máquina hace todas las operaciones necesarias y proporciona las ecuaciones adecuadas. Este de hoy es un problema clásico: se trata de determinar el alcance de un disparo parabólico a partir de la velocidad inicial y de la inclinación sobre el suelo. Para resolverlo se descompone la velocidad inicial en dos componentes: la velocidad horizontal y la vertical. Contra esta trabaja la gravedad. De esta forma obtenemos dos ecuaciones para el desplazamiento: sy=vy*t + ½g*t²  y   sx=vx*t, siendo sy y sx los desplazamientos vertical y horizontal. Teniendo en cuenta que g es negativa en el ascenso y que cuando el proyectil llega al suelo sy=0 obtenemos una ecuación de 2º grado que resolvemos para t. Una vez obtenido t resolvemos la segunda ecuación para obtener sx.
Combinando estos cálculos llegamos a la fórmula sintética, que también podemos emplear: 
sx= v²*sin(2a)/g.
En esa fórmula podemos ver dos cosas: que el alcance depende fuertemente de la velocidad inicial y que es máximo para 45º, pues seno(2*45) = seno (90) = 1. También podemos derivar respecto a  'a', sx' = v²/g cos(2a) y ver que para a=pi/4  cos(pi/2)=0, marcando el máximo de la primitiva.
P.D. He añadido una linea al programa para calcular la altura máxima que alcanza el proyectil en su movimiento parabólico. La fórmula es sy=v²*sin²(a)/2*g.
Esta fórmula se puede obtener fácilmente derivando respecto de t  sy=v*sin(a)*t + ½g*t² e igualando a cero. Obtenemos t=2*v*sin(a)/g. Sustituyendo este valor de t en la función sy obtenemos la fórmula.


#include<iostream>
#include<cmath>
#define g 9.81
#define pi 3.14159265
using namespace std;
int main()
{
//Variables
double v,vx,vy; //velocid. inicial, componentes de la velocidad.
double a,sx,t; //ang. inclin.,distancia horiz.,tiempo empleado
cout<<"\n\tCalcular el alcance de un proyectil lanzado con una velocidad \n";
cout<<"\tinicial 'v' y con un angulo de inclinación sobre el suelo 'alfa'.\n"<<endl;
//Entrada de Datos
cout<<"Dame velocidad del disparo (metros/seg): ";cin>>v;
cout<<"Dame ángulo de inclinación (grados): ";cin>>a;
a=a*pi/180; //conversión a radianes
//Fórmulas: componentes de la velocidad
vx=v*cos(a);
vy=v*sin(a);
//Solución de la ecuación de 2º grado: -9.8*t*t/2 + vy*t=0, pues cuando llega al suelo sy=0
t=vy/(g/2);
sx=vx*t;
//También: sx=v*cos(a)*v*sin(a)/(g/2) ==> sx=v²sin(2a)/g
//Resultados
cout<<"El alcance del disparo es: "<<sx<<" ms."<<endl;
cout<<"El tiempo que tarda en alcanzar el objetivo es: "<<t<<" seg."<<endl;
cout<<"La altura máxima que alcanza es: "<<v*v*sin(a)*sin(a)/(2*g)<<" ms."<<endl;
return 0;
}

jueves, 13 de junio de 2013

Las máquinas y los problemas



Una cosa que siempre me atrajo es esta de resolver "problemas tipo". Me explico: Ya que tenemos "máquinas calculadoras" que son los ordenadores - que para eso nacieron fundamentalmente - vamos a dejarle a la máquina hacer todos los cálculos con los datos que le entreguemos y el programa adecuado en cada caso. Los datos pueden ser cualesquiera - eso sí, dentro de un orden - y la máquina se encargará de hacer los cálculos. Esto de hacer los cálculos, me temo yo, pasará en el futuro completamente a su dominio. Pero lo que nunca podrán hacer las máquinas son los planteamientos y la utilización de las fórmulas adecuadas. Eso es lo que nosotros les proporcionamos por medio del programa. Programar debiera ser tan fácil como escribir una carta o redactar un mensaje. Y todo el mundo debiera saber hacerlo. Es lo que apareció con aquellas calculadoras de hace 30 años "programables". Aquello nos parecía una "pasada" y realmente que lo era. Pues ahora lo tenemos mucho más fácil con los lenguajes de programación. Y sin embargo probablemente lo despreciamos porque pretendemos hacer programas más "sofisticados" y huimos de lo trillado. Pues bien, he aquí un ejemplo de lo que pretendo decir. Este es un problema tipo y típico de plano inclinado y aceleraciones. Como este se pueden hacer miles y convendría ejercitarse para llegar a dominar completamente esta forma de proceder. En la segunda pantalla hay un pequeño error: la aceleración debe ser dada en mts/seg².


#include<iostream>
#include<cmath>
using namespace std;
#define pi 3.1415926
#define g 9.81
int main()
{
double s,t,v;
double a,t_v,s_v;
double h,i_p;
//Texto
cout<<"\n\t  Un cuerpo, partiendo del reposo, cae por un \n";
cout<<"\t  plano inclinado con un aceleración uniforme\n";
cout<<"\t  recorriendo 'x' metros en 't' segundos.\n";
cout<<"\t  ¿Cuanto tiempo tardará en adquirir una velo-\n ";
cout<<"\t  cidad 'v' desde que empieza a moverse?"<<endl;
cout<<endl;
//Datos
ini:
cout<<"Dame el espacio recorrido por el cuerpo en su descenso por el plano (m): ";cin>>s;
cout<<"Dame el tiempo empleado en recorrer ese espacio (seg): ";cin>>t;
a=(2*s)/(t*t); //cálculo de la aceleración
if(a>=g) {cout<<"Imposible, hay un error. \n";goto ini;} //no se puede alcanzar la aceleración de la gravedad
cout<<"Dame la velocidad final que debe llegar a alcanzar (m/s): ";cin>>v;
//Otras fórmulas
t_v=v/a; //tiempo para alcanzar velocidad final
s_v=a*t_v*t_v/2; //espacio recorrido
h=a*s_v/g; //altura del plano
i_p=asin(h/s_v); //ángulo de inclinación
//Resultados
cout<<"La aceleración del movimiento es de "<<a<<" m/s. "<<endl;
cout<<"El tiempo que tardará en adquirir esa velocidad es de "<<t_v<<" seg. "<<endl;
cout<<"Para entonces el cuerpo habrá recorrido un espacio de "<<s_v<<" metros"<<endl;
cout<<"Comprobación: La velocidad final al cuadrado ha de ser igual al doble de la\n";
cout<<" aceleración por el espacio recorrido. Efectivamente, velocidad final² = "<<v*v<<endl;
cout<<"Y el doble de la aceleración por el espacio recorrido: "<<2*a*s_v<<endl;
cout<<"La altura desde la que cayó ese cuerpo para adquirir esa velocidad es de "<<h<<" m"<<endl; 
cout<<"Y la inclinación del plano "<<i_p*180/pi<<" grados."<<endl;
return 0;
}


jueves, 6 de junio de 2013

Un ejemplo de programación POO



Este programa lo he tomado del libro de Francisco Javier Ceballos "C++ orientado a objetos". Nos indica un poco cómo funciona esto de la programación orientada a objetos. Es un ejemplo elemental de administración de una cuenta en un banco, por ejemplo. Está ligeramente retocado, porque hay algunas cosas que no entiendo.


#include<iostream>
#include<string>
using namespace std;
class CCuenta
{
//Atributos
private:
string nombre;
string cuenta;
double saldo;
double tipoInteres;
//Métodos
public:
void asignarNombre(string nom){
if(nom.length()==0){ cout << "error: cadena vacía\n"; return;}
nombre=nom;
}
string obtenerNombre(){
return nombre;
}
void asignarCuenta(string cue){
if (cue.length()==0){cout << "Error: cuenta no válida\n";return;}
cuenta = cue;
}
string obtenerCuenta(){
return cuenta;
}
void asignarRemanente(double remanente){
saldo=remanente;
return;
}
double estado(){
return saldo;
}
void ingreso(double cantidad) {
if (cantidad<0){cout<<"Error: cantidad negativa\n";return;}
saldo=saldo+cantidad;
}
void reintegro(double cantidad){
if(saldo - cantidad <0) {cout <<"Error: No dispone de saldo\n";return;}
saldo = saldo - cantidad;
}
void asignarTipoDeInteres(double tipo){
if (tipo<0) {cout <<"Error: Tipo no válido\n";return; }
tipoInteres = tipo;
}
double obtenerIntereses(){
return saldo*tipoInteres/100;
}
};
int main(){
string num,nombre;
double interes, cantidad, salida, remanente;
CCuenta cuenta01; //Asignación de un objeto a la clase CCuenta
cout<<"Déme el nombre del titular de la cuenta: ";getline(cin,nombre);
cuenta01.asignarNombre(nombre);
cout<<"Déme el número de su cuenta: ";cin>>num;
cuenta01.asignarCuenta(num);
cout<<"Déme el remanente de su cuenta: ";cin>>remanente;
cuenta01.asignarRemanente(remanente);
cout<<"¿Cuánto va a ingresar? ";cin>>cantidad;
cuenta01.ingreso(cantidad);
cout<<"¿Cuánto va a sacar?: ";cin>>salida;
cuenta01.reintegro(salida);
cout<<"El titular de la cuenta es el Sr. "<<cuenta01.obtenerNombre()<<endl;
cout<<"Su número de cuenta es "<<cuenta01.obtenerCuenta()<<endl;
cout<<"El estado de su cuenta es "<<cuenta01.estado()<<endl;
cuenta01.asignarTipoDeInteres(2.5);
cout<<"Los intereses que producirán su depósito al 2.5 % son "<<cuenta01.obtenerIntereses()<<endl;
}