Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Saber si en mrua habrá alcance o nunca se encontraran

Estas en el tema de Saber si en mrua habrá alcance o nunca se encontraran en el foro de C/C++ en Foros del Web. Hola amigos, hablando con un profesor de matemáticas sobre MRUA Y MRUR le pregunté que que devolverian las fórmulas matemáticas si por ejemplo A sale ...
  #1 (permalink)  
Antiguo 17/05/2016, 14:55
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Saber si en mrua habrá alcance o nunca se encontraran

Hola amigos, hablando con un profesor de matemáticas sobre MRUA Y MRUR le pregunté que que devolverian las fórmulas matemáticas si por ejemplo A sale en persecucion de B, A tiene mayor velocidad que B y la aceleración podría ser menor, mayor o igual, si ambos se detienen antes de producirse el alcance o si A se detiene.
Me dijo que las fórmulas matemáticas si me darían un resultado pero que quedaría a criterio mio si el resultado es válido o no ya que las matemáticas no podían resolver ese problema.
Entonces se me ocurrió hacer un minicodigo que me pida todos los datos necesarios y usando fuerza bruta vaya incrementando el tiempo y aplicando las fórmulas comparando las posiciones después de x segundos. El código lo he conseguido hacer funcionar pero no me gusta como lo resolví.
Imaginen este caso:
A sale de la posición 1 a 20m/s con una aceleración de 5m/s^2.
B sale de la posición 2 a 50m/s con una aceleración de 4m/s^2.
Ambos están distanciados 5000 metros.
Como la aceleración de A es mayor que la de B es seguro que A acabará tarde o temprano alcanzando a B con lo que con comprobar las aceleraciones sabría si seria posible que A alcance a B.
Ahora imaginen:
A va a 100m/s con una aceleración de 5m/s^2
B va a 50m/s con una aceleración de 6m/s^s
Dependiendo de la distancia entre ellos será posible que A alcance a B aunque su aceleración sea menor porque su velocidad es mayor.
Entonces no basta con comparar la aceleración.
Mi solución es calcular la velocidad de ambos segundo a segundo y voy comparándolas segundo a segundo y si B lleva mayor velocidad que A incremento un contador. Ese contador tiene un límite de 100000 así que si el contador llega a 100000 quiere decir que en esos segundos A no ha conseguido alcanzar una velocidad superior a la de B y se da por echo que nunca lo alcanzará. Funcionar funciona pero no es totalmente cierto.
¿como solucionaríais ustedes esto? Mañana de todos modos os pongo el código para que lo vean y me den más tipos para corregir cosas que veáis.
El código funciona tanto para MRUA como para MRUR solo que para el segundo se pasan las aceleraciones negativas.
  #2 (permalink)  
Antiguo 17/05/2016, 15:24
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 4 años, 6 meses
Puntos: 27
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

No entiendo por qué no puedes resolver esto matemáticamente, de hecho es un tipo de problema bastante común al menos cuando yo lo dí en el instituto.
  #3 (permalink)  
Antiguo 17/05/2016, 15:31
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Pues en un caso que le comente a el resulta que ambos objetos se detienen antes de encontrarse con lo que las velocidades empiezan a volverse negativas, vamos que irían los objetos hacia atrás y seria B quien podría alcanzar a A y daba que A alcanzaba a B en más de 3 años. Me dijo que solución matemática tenia como podía ver pero que no era lógica con lo que había que desecharla. Con mi código si que te muestra si es factible o no el alcance y no admite el cambio de sentido con lo que cuando su velocidad sea 0 contará que se queda parado ahí.
  #4 (permalink)  
Antiguo 17/05/2016, 15:51
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 4 años, 6 meses
Puntos: 27
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Creo que eso también se puede resolver directamente matemáticamente sólo que de otra manera al caso anterior. Supongamos que ambos tienen una aceleración negativa, es decir los dos acabarán parandose.

Suponemos que la posición inicial de A es menor que la de B (A supuestamente persigue a B)
1 - Calculas el tiempo que cada objeto ha tardado en alcanzar la situación de reposo.
2 - Calculas la posición obtenida aplicando los tiempos calculados respectivamente.

Entonces,
si posicion(A) < posicion(B) no hay solución
si posicion(A) = posicion(B) la solución está en el punto de reposo
si posicion(A) > posicion(B) lanzando el algoritmo normal obtienes una solución válida.
  #5 (permalink)  
Antiguo 18/05/2016, 00:42
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Eso no es del todo cierto porque puede ser que A alcance a B y al tener mayor aceleración A se detenga después de que B se haya alejado y luego se para B. Si haces lo que dices te dará que A no alcanza a B aunque eso no sea verdad. Calculando segundo a segundo es menos probable que eso pase ya que para ser totalmente fiel habría que usar milisegundos.
  #6 (permalink)  
Antiguo 18/05/2016, 01:48
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

aguml no te compliques. Si sacas la ecuación del movimiento de ambos cuerpos e igualas podrás encontrar 0, 1 o dos soluciones:

Si asumimos aceleración constante, la posición de un cuerpo viene determinada por la ecuación : p = x0+v0*t+a0*t^2. Si tienes dos objetos diferentes, entonces:

x0+v0*t+a0*t^2=x1+v1*t+a1*t^2, luego 0=(x0-x1)+(v0-v1)t+(a0-a1)t^2 = c+bt+at^2. De esta última equación se deducen dos raices:

t0 = (-b + (b^2-4*ac)^0.5) / 2*a y t1= (-b - (b^2-4*ac)^0.5) / 2*a

Por supuesto puede que las soluciones tengan componente imaginaria. Como nos estamos moviendo en el plano real se asume que no son solución a nuestro problema.

Estas ecuaciones nos plantean los siguientes escenarios:
  • No se cruzan: Las dos raices son imaginarias o t1 y t2 son negativos
  • Un único cruce: Una raiz es positiva y la otra negativa
  • Dos cruces: t0 y t1 son positivos
Queda claro que todo t<0 no es solución válida ya que no creo que tus objetos vayan a viajar en el tiempo.

El caso es que una vez tienes las posibles soluciones válidas la cosa es comprobar si la velocidad ha pasado a ser negativa antes de llegar a la solución... eso lo puedes verificar comprobando el punto en el que se encuentra el objeto en el tiempo t. Si la velocidad es positiva y xf<xi entonces es que los objetos han dado media vuelta y se han encontrado cuando iban en dirección contraria.

Algunos ejemplos:

EJ 1
x0 = 5, v0=2, a0=2
x1 = 10, v1=3, a1=1
a=1, b=-1, c=-5

Raices:
t0 = 2.79
t1 = -1.79 -> no válida

Solución: Se cruzan en t=2.79, es decir, en x=(5+2*2.79+2*2.79^2)=26,16

EJ 2
x0 = 5, v0=2, a0=1
x1 = 10, v1=3, a1=1
a=-1, b=-1, c=-5

Raices:
t0 = imaginaria
t1 = imaginaria

Solución: No se cruzan

EJ 3
x0 = 5, v0=20, a0=-1
x1 = 10, v1=30, a1=-2
a=1, b=-10, c=-5

Raices:
t0 = 10.47
t1 = -0.47

Solución: Se cruzan en t=10.47, es decir, en x=104.77

EJ 4
x0 = 5, v0=5, a0=-1
x1 = 10, v1=30, a1=-2
a=1, b=-25, c=-5

Raices:
t0 = 25.19
t1 = -0.19

Solución: Se cruzan en t=25.19, es decir, en x=-503.96 -> Se han parado y han empezado a ir hacia atrás, luego no se cruzan antes de pararse.

Si ahora presupones que la aceleración no es constante sino que varía con el tiempo en base a una función dada la solución se complica ligeramente porque ahora te tocaría ingegrar la aceleración... si resulta que la función es continua los cálculos se simplifican.... y lo mismo es aplicable para la velocidad.

Como ves, no es tan complicado encontrar la solución al problema.

Un saludo
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #7 (permalink)  
Antiguo 18/05/2016, 07:39
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Cuando dices que las soluciones son imaginarias ¿por qué dices eso? ¿cual es el resultado imaginario? ¿saldría una raíz cuadrada negativa o algo así? En el resto de casos esta claro que un tiempo negativo se descarta pero un valor imaginario que criterio sigues para descartar lo?
Ya estuve haciendo pruebas con eso aplicando como haces tu la ecuación para cuadráticas pero no tenia muy claro como descartar algunos resultados como cuando daba dos positivos elegir el correcto y cosas así.
  #8 (permalink)  
Antiguo 18/05/2016, 08:20
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

los números imaginarios parten de j=(-1)^0.5, es decir, la raiz de menos uno. Si intentas hallar con una calculadora normal el resultado de la raiz de un número negativo te dará error... mientras que si lo haces con una científica obtendrás un número acompañado de j.

Por supuesto los números imaginarios pueden acompañar a números reales (p.ej: 4 + 5j), pero no puedes mezclarlos ya que son como agua y aceite.

El sistema de ecuaciones que te he planteado pretende calcular el punto de encuentro en el plano real, no en el imaginario. Si el resultado tiene parte imaginaria quiere decir que no tiene un resultado real puro, luego no es solución al sistema y es algo que puedes verificar con los ejemplos que te he puesto.

Si necesitas más información sobre los números imaginarios lo mejor es que busques en Internet ya que la teoría de los mismos no tiene demasiada cabida en un foro de programación.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #9 (permalink)  
Antiguo 18/05/2016, 13:11
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Hay un fallo en tu fórmula y los resultados que te da son todos erróneos.
Estoy liado con la solución que me indicas pero tiene algunas pegas. Lo que yo quiero es que cuando un objeto va con aceleración negativa y llega a 0 podríamos decir que se produce un efecto yoyó y empieza a ir para atrás con la misma aceleración. Yo quiero que cuando llegue a 0 ese objeto se quede parado y eso con esas fórmulas no se puede. Usando mi código, como controlo al segundo las velocidades si puedo hacer que cuando llegue a 0 se pare.
La solución que planteas la tengo casi lista pero tengo algunos problemas a la hora de verificar si el tiempo es válido o no porque me he liado un poco y necesito dejarlo para mañana porque ya no se ni que hago y la voy a liar.
Mañana lo retomo y si no lo consigo ya pido ayuda.
Para que os hagáis una idea tengo una sola función para todos los casos posibles y a esta le paso un puntero a función para verificar las velocidades. Si es MRUR le paso un puntero a la función de verificación para los MRUR y si es s MRUA le paso un puntero a la función de verificación para los MRUA y con eso consigo con solo esas 3 funciones poder realizar los cálculos y verificación para todos los casos.
Dependiendo de cada caso juego con pasar las velocidades y/o aceleraciones en positivo o negativo y ahí es donde tengo ahora mismo un cacao. Tengo que seguir haciendo pruebas.

Última edición por aguml; 18/05/2016 a las 13:21
  #10 (permalink)  
Antiguo 19/05/2016, 04:16
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 4 años, 10 meses
Puntos: 204
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Voy a empezar de 0 porque con las ediciones que hice al final es cierto que metí la pata.

La ecuación de la velocidad suponiendo una aceleración constante es v(t)=a0t+v0. En consecuencia, la posición dada por dicha velocidad se calcula integrando la anterior ecuación, lo que resulta en p(t)=(a0/2)*t^2+v0t+p0.

Con esta ecuación ya calculada podemos empezar a trabajar. Lo primero es calcular el momento en el que se cruzan. Como los dos objetos van a tener aceleración constante únicamente pueden cruzarse, a lo sumo, una vez y esto es así porque la posición únicamente depende del tiempo, luego existe una relación de proporcionalidad entre la posición de los dos objetos.

El caso es que ambos objetos se encontrarían cuando p1(t)=p2(t), es decir, cuando (a1/2)*t^2+v1t+p1=(a2/2)*t^2+v2t+p2. Si esta última ecuación la transformamos para trabajar con ella obtenemos dos posibles soluciones que básicamente nos van a dar el mismo resultado:
  • ((a1-a2)/2)*t^2+(v1-v2)*t-(p1-p2)=0
  • ((a2-a1)/2)*t^2+(v2-v1)*t-(p2-p1)=0

Estas ecuaciones no son más que un polinomio de grado dos (at^2+bt+c=0) y sus raices se pueden calcular mediante las ecuaciones:
  • r1 = (-b - sqrt(b^2-4ac))/2a
  • r2 = (-b + sqrt(b^2-4ac))/2a

Como hemos comentado como mucho una de estas dos raices indicará un punto de cruce, la otra o tendrá parte imaginaria o dará un valor negativo... estamos hablando de tiempo y se asume que el tiempo ha de avanzar, no retroceder.

Vale, supongamos que hemos encontrado un punto de cruce en t=r. Si no hubiese restricciones en cuanto al movimiento de los objetos esa sería nuestra solución final... sin embargo una restricción es que si un objeto alcanza velocidad 0 se detiene y ya no se mueve. Esta restricción podemos tratarla de la siguiente forma:
  • Calculamos el tiempo necesario para parar cada objeto. Al igual que sucedía con los puntos de cruce este cálculo puede arrojar 0 o 1 soluciones posibles.
  • Si el tiempo anterior es mayor que el tiempo que tardan en cruzarse descartamos el tiempo de la parada... nos interesa saber dónde se cruzan, lo que hagan despues...
  • Si resulta que ambos objetos se para antes del tiempo de cruce entonces no se van a cruzar nunca... obvio, no?
  • Si solo un objeto se para antes del cruce podemos hacer lo siguiente:
    • Calculamos el punto en el que se para el objeto
    • Calculamos el tiempo que tardará el segundo objeto en alcanzar dicha posición
    • Comprobamos si el segundo objeto se para o no antes de llegar a esta nueva posición

Y ya está... después de todo este proceso pueden pasar dos cosas:
  • Que tengamos un tiempo válido. Esto implica que ambos objetos se cruzan después de todo
  • Que tengamos un tiempo no válido. Es decir, no se cruzan.

En el caso de que se crucen basta con verificar la posición de cualquiera de los objetos en el tiempo hallado y listo.

Una forma de hacerlo con C++:

Código C++:
Ver original
  1. #include <array>
  2. #include <iostream>
  3. #include <cmath>
  4. #include <memory>
  5.  
  6. enum ParamIndex
  7. {
  8.     Aceleracion,
  9.     Velocidad,
  10.     Posicion
  11. };
  12.  
  13. using ParamsObj = std::array<double,3>;
  14. using NullDouble = std::unique_ptr<double>;
  15.  
  16. constexpr bool SonEquivalentes(double a, double b)
  17. {
  18.   return fabs(a-b) < 1e-8;
  19. }
  20.  
  21. NullDouble CalcularTiempoParada(ParamsObj const& obj)
  22. {
  23.   NullDouble toReturn;
  24.  
  25.   auto a = obj[Aceleracion];
  26.   auto v = obj[Velocidad];
  27.  
  28.   if( !SonEquivalentes(a,0) && !SonEquivalentes(v,0) )
  29.   {
  30.     auto tiempo = -v/a;
  31.     if( tiempo > 0. )
  32.       toReturn = std::make_unique<double>(tiempo);
  33.   }
  34.  
  35.   return toReturn;
  36. }
  37.  
  38. NullDouble CalcularTiempoCruce(ParamsObj const& obj1, ParamsObj const& obj2)
  39. {
  40.   NullDouble toReturn;
  41.  
  42.   auto a = (obj1[Aceleracion]-obj2[Aceleracion])/2;
  43.   auto b =  obj1[Velocidad]  -obj2[Velocidad];
  44.   auto c =  obj1[Posicion]   -obj2[Posicion];
  45.  
  46.   if( SonEquivalentes(a,0) ) // Si no hay aceleración
  47.   {
  48.     auto tiempo = -c/b;
  49.     if( tiempo > 0 )
  50.       toReturn = std::make_unique<double>(tiempo);
  51.   }
  52.   else
  53.   {
  54.     int raiz = b*b-4*a*c;
  55.  
  56.     if( raiz > 0 )
  57.     {
  58.       auto tiempo = (-b + sqrt(raiz))/(2*a);
  59.       if( (tiempo < 0) || !std::isfinite(tiempo) )
  60.         tiempo = (-b - sqrt(raiz))/(2*a);
  61.       if( (tiempo > 0) && std::isfinite(tiempo) )
  62.         toReturn = std::make_unique<double>(tiempo);
  63.     }
  64.   }
  65.  
  66.   return toReturn;
  67. }
  68.  
  69. double CalcularPosicion(ParamsObj const& obj, double tiempo)
  70. {
  71.   auto a = obj[Aceleracion];
  72.   auto v = obj[Velocidad];
  73.   auto p = obj[Posicion];
  74.  
  75.   return ((a*pow(tiempo,2))/2)+(v*tiempo)+p;
  76. }
  77.  
  78. void Comprobar(ParamsObj const& obj1, ParamsObj const& obj2)
  79. {
  80.   std::cout << "Condiciones iniciales:\n"
  81.             << "\tObjeto 1: a=" << obj1[Aceleracion] << ", v=" << obj1[Velocidad] << ", x=" << obj1[Posicion] << "\n"
  82.             << "\tObjeto 2: a=" << obj2[Aceleracion] << ", v=" << obj2[Velocidad] << ", x=" << obj2[Posicion] << "\n"
  83.             << "\n\nResultado:\n";
  84.  
  85.   auto tiempo = CalcularTiempoCruce(obj1, obj2);
  86.   NullDouble posicion;
  87.  
  88.   if( tiempo )
  89.   {
  90.     auto t1 = CalcularTiempoParada(obj1);
  91.     auto t2 = CalcularTiempoParada(obj2);
  92.  
  93.     bool usarT1 = ( t1 && *t1 < *tiempo );
  94.     bool usarT2 = ( t2 && *t2 < *tiempo );
  95.  
  96.     // Si ambos se paran antes del cruce entonces no se cruzan
  97.     if( usarT1 && usarT2 )
  98.     {
  99.       usarT1 = usarT2 = false;
  100.       t1.reset();
  101.       t2.reset();
  102.       tiempo.reset();
  103.     }
  104.  
  105.     // Si alguno se para antes del cruce hay que reajustar las fórmulas
  106.     if( usarT1 )
  107.     {
  108.       auto pos = CalcularPosicion(obj1,*t1);
  109.       ParamsObj newObj1 = { 0, 0, pos };
  110.       tiempo = CalcularTiempoCruce(newObj1,obj2);
  111.  
  112.       if( tiempo )
  113.       {
  114.         if( !t2 || *tiempo < *t2 )
  115.           posicion = std::make_unique<double>(pos);
  116.         else
  117.           tiempo.reset();
  118.       }
  119.     }
  120.     else if( usarT2 )
  121.     {
  122.       auto pos = CalcularPosicion(obj2,*t1);
  123.       ParamsObj newObj2 = { 0, 0, pos };
  124.       tiempo = CalcularTiempoCruce(obj1,newObj2);
  125.  
  126.       if( tiempo )
  127.       {
  128.         if( !t1 || *tiempo < *t1 )
  129.           posicion = std::make_unique<double>(pos);
  130.         else
  131.           tiempo.reset();
  132.       }
  133.     }
  134.   }
  135.  
  136.   if( tiempo )
  137.   {
  138.     auto pos = (posicion)? *posicion : CalcularPosicion(obj1,*tiempo);
  139.     std::cout << "\tLos objetos se cruzan en p=" << pos
  140.               << ", en t=" << *tiempo << "\n";
  141.   }
  142.   else
  143.   {
  144.     std::cout << "\tNo se cruzan\n";
  145.   }
  146. }
  147.  
  148.  
  149. int main()
  150. {
  151.   std::cout << "EJEMPLO1: El objeto de atrás va mas rápido\n";
  152.   ParamsObj paramsObj1 = { 2 /*aceleracion*/, 2 /*velocidad*/,  5 /*posicion*/};
  153.   ParamsObj paramsObj2 = { 1 /*aceleracion*/, 3 /*velocidad*/, 10 /*posicion*/};
  154.   Comprobar(paramsObj1,paramsObj2);
  155.  
  156.   std::cout << "\nEJEMPLO2: El objeto de delante va mas rápido\n";
  157.   paramsObj1 = { 1 /*aceleracion*/, 2 /*velocidad*/,  5 /*posicion*/};
  158.   paramsObj2 = { 1 /*aceleracion*/, 3 /*velocidad*/, 10 /*posicion*/};
  159.   Comprobar(paramsObj1,paramsObj2);
  160.  
  161.   std::cout << "\nEJEMPLO3: El objeto mas adelantado frena mas rapido\n";
  162.   paramsObj1 = { -1 /*aceleracion*/, 10 /*velocidad*/, 5 /*posicion*/};
  163.   paramsObj2 = { -3 /*aceleracion*/, 10 /*velocidad*/, 7 /*posicion*/};
  164.   Comprobar(paramsObj1,paramsObj2);
  165.  
  166.   std::cout << "\nEJEMPLO4: Ambos objetos se paran antes de encontrarse\n";
  167.   paramsObj1 = { -1 /*aceleracion*/, 5 /*velocidad*/,  5 /*posicion*/};
  168.   paramsObj2 = { -2 /*aceleracion*/, 30 /*velocidad*/, 10 /*posicion*/};
  169.   Comprobar(paramsObj1,paramsObj2);
  170.  
  171.   std::cout << "\nEJEMPLO5: Un objeto se para y el otro le da caza\n";
  172.   paramsObj1 = { -1 /*aceleracion*/, 10 /*velocidad*/,  1000 /*posicion*/};
  173.   paramsObj2 = { 0 /*aceleracion*/, 2 /*velocidad*/, 0 /*posicion*/};
  174.   Comprobar(paramsObj1,paramsObj2);
  175.  
  176.   std::cout << "\nEJEMPLO6: Cada objeto va en un sentido y no se cruzan\n";
  177.   paramsObj1 = { -1 /*aceleracion*/, -1 /*velocidad*/,  -1 /*posicion*/};
  178.   paramsObj2 = { 1 /*aceleracion*/, 1 /*velocidad*/, 1 /*posicion*/};
  179.   Comprobar(paramsObj1,paramsObj2);
  180.  
  181.   std::cout << "\nEJEMPLO7: Objetos enfrentados se encuentran a mitad de camino\n";
  182.   paramsObj1 = { -1 /*aceleracion*/, -1 /*velocidad*/,  10 /*posicion*/};
  183.   paramsObj2 = { 1 /*aceleracion*/, 1 /*velocidad*/, -5 /*posicion*/};
  184.   Comprobar(paramsObj1,paramsObj2);
  185.  
  186.   std::cout << "\nEJEMPLO8: Objetos enfrentados se paran cerca pero antes de encontrarse\n";
  187.   paramsObj1 = { 1 /*aceleracion*/, -1 /*velocidad*/,  10 /*posicion*/};
  188.   paramsObj2 = { -1 /*aceleracion*/, 1 /*velocidad*/, -5 /*posicion*/};
  189.   Comprobar(paramsObj1,paramsObj2);
  190.   return EXIT_SUCCESS;
  191. }
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 19/05/2016 a las 04:40
  #11 (permalink)  
Antiguo 19/05/2016, 11:25
 
Fecha de Ingreso: febrero-2015
Mensajes: 400
Antigüedad: 4 años, 5 meses
Puntos: 3
Respuesta: Saber si en mrua habrá alcance o nunca se encontraran

Bueno, he estado fuera y he estado liado con esto. Como no tenia internet no pude ver lo que me indicas y he sacado una solucion que me funciona pero no se si la he liado mucho o no jejeje:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4.  
  5. typedef enum {positiva,negativa}Aceleracion;
  6.  
  7. typedef struct{
  8.    double VelocidadInicial;
  9.    double VelocidadFinal;
  10.    double PosicionInicial;
  11.    double PosicionFinal;
  12.    double aceleracion;
  13. }InfoObjeto;
  14.  
  15. int Menu(void);
  16. void ObtenerDatos(InfoObjeto *A,InfoObjeto *B);
  17. int Verificar(double t,InfoObjeto *A,InfoObjeto *B);
  18. int VerificarTiempos(double t1,double t2,InfoObjeto *A,InfoObjeto *B);
  19. void ReajustarDatos(InfoObjeto *A, InfoObjeto *B, Aceleracion a);
  20. int CalcularTiempos(double *t1,double *t2,InfoObjeto A,InfoObjeto B);
  21. //---------------------------------------------------------------------------
  22.  
  23. void MostrarInfo(double t,InfoObjeto A,InfoObjeto B)
  24. {
  25.    printf("A alcanza a B a los %lf segundos.\n",t);
  26.    printf("En ese tiempo:\n");
  27.    printf("\tA lleva una velocidad de %lf m/s.\n",A.VelocidadFinal);
  28.    printf("\tB lleva una velocidad de %lf m/s.\n",B.VelocidadFinal);
  29.    printf("\tA recorre %lf metros.\n",A.PosicionFinal - A.PosicionInicial);
  30.    printf("\tB recorre %lf metros.\n\n",B.PosicionInicial + B.PosicionFinal);
  31. }
  32. //---------------------------------------------------------------------------
  33.  
  34. int Verificar(double t, InfoObjeto *A, InfoObjeto *B)
  35. {
  36.    //V_f(t) = V0 + a * t;
  37.    int alcanza;
  38.    double V_fA, V_fB;
  39.  
  40.    if(t >= 0){
  41.       V_fA = A->VelocidadInicial + (A->aceleracion * t);
  42.       V_fB = B->VelocidadInicial + (B->aceleracion * t);
  43.       if(V_fA < 0 || V_fB < 0){
  44.          alcanza=0;
  45.       }else{
  46.          A->VelocidadFinal = V_fA;
  47.          B->VelocidadFinal = V_fB;
  48.          A->PosicionFinal = A->PosicionInicial + (A->VelocidadInicial * t)+(0.5 * A->aceleracion * pow(t,2));
  49.          B->PosicionFinal = B->PosicionInicial + (B->VelocidadInicial * t)+(0.5 * B->aceleracion * pow(t,2));
  50.          if(B->PosicionFinal < 0)
  51.             B->PosicionFinal = fabs(B->PosicionFinal);
  52.          alcanza=1;
  53.       }
  54.    }else{
  55.       alcanza=0;
  56.    }
  57.    return alcanza;
  58. }
  59. //---------------------------------------------------------------------------
  60.  
  61. //Esta funcion lo que hace es reajustar los datos para que valgan para la aceleracion elegida
  62. void ReajustarDatos(InfoObjeto *A, InfoObjeto *B, Aceleracion a)
  63. {
  64.    //Coloco las velocidades iniciales en positivo para una correcta verificacion
  65.    A->VelocidadInicial = fabs(A->VelocidadInicial);
  66.    B->VelocidadInicial = fabs(B->VelocidadInicial);
  67.  
  68.    //Coloco las aceleraciones en negativo si son negativas y en positivo si son positivas
  69.    if(a == positiva){
  70.       A->aceleracion = fabs(A->aceleracion);
  71.       B->aceleracion = fabs(B->aceleracion);
  72.    }else{
  73.       A->aceleracion = -fabs(A->aceleracion);
  74.       B->aceleracion = -fabs(B->aceleracion);
  75.    }
  76. }
  77. //---------------------------------------------------------------------------
  78.  
  79. int VerificarTiempo(double t, InfoObjeto *A, InfoObjeto *B)
  80. {
  81.    int alcanza=0;
  82.  
  83.    //Si en el momento del alcance las velocidades no son ninguna de ellas negativas
  84.    //querrá decir que se encontraron antes de invertirse su sentido y será válida
  85.    if(Verificar(t,A,B) == 1){
  86.       A->PosicionInicial = fabs(A->PosicionInicial);
  87.       B->PosicionInicial = fabs(B->PosicionInicial);
  88.       B->PosicionFinal = -fabs(B->PosicionFinal);
  89.       alcanza=1;
  90.    }
  91.    return alcanza;
  92. }
  93. //---------------------------------------------------------------------------
  94.  
  95. int CalcularTiempos(double *t1, double *t2, InfoObjeto A, InfoObjeto B)
  96. {
  97.    //X_0A + (V_0A * t)+((1/2) * a_A * t^2) = X_0B + (V_0B * t) + ((1/2) * a_B * t^2);
  98.  
  99.    double c, b, a;
  100.    int validos=0;
  101.  
  102.    c = A.PosicionInicial + B.PosicionInicial;
  103.    b = A.VelocidadInicial + B.VelocidadInicial;
  104.    a = (0.5 * A.aceleracion) + (0.5 * B.aceleracion);
  105.  
  106.    //Si a es negativo no se puede calcular una raiz de un negativo asi que multiplico todos por -1 para cambiar sus signos
  107.    if(a < 0){
  108.       c *= -1;
  109.       b *= -1;
  110.       a *= -1;
  111.    }
  112.  
  113.    //Calculo ambos tiempos
  114.    if(a==0 && b != 0){
  115.       *t1 = fabs(c)/fabs(b);
  116.       *t2 = -1;
  117.    }else if(a != 0){
  118.       *t1 = (-b + sqrt((pow(b,2) - (4 * a * c))))/(2*a);
  119.       *t2 = (-b - sqrt((pow(b,2) - (4 * a * c))))/(2*a);
  120.    }
  121.    return validos;
  122. }
  123. //---------------------------------------------------------------------------
  124.  
  125. int Menu(void)
  126. {
  127.    int op;
  128.    printf("Calculos con MRU, MRUA y MRUR\n");
  129.    printf("=============================\n");
  130.    printf("1.Calcular tiempo en MRUA con encuentro\n");
  131.    printf("2.Calcular tiempo en MRUA con persecucion\n");
  132.    printf("3.Calcular tiempo en MRUR con encuentro\n");
  133.    printf("4.Calcular tiempo en MRUR con persecucion\n");
  134.    printf("5.Salir\n");
  135.    printf("\nNOTA: Para MRU use cualquiera las opciones de arriba con aceleracion 0.\n");
  136.    printf("\nElige una opcion: ");
  137.    scanf("%d",&op);
  138.  
  139.    return op;
  140. }
  141. //---------------------------------------------------------------------------
  142.  
  143. void ObtenerDatos(InfoObjeto *A, InfoObjeto *B)
  144. {
  145.    printf("Introduce la posicion inicial de A: ");
  146.    scanf("%lf",&A->PosicionInicial);
  147.    printf("Introduce la velocidad de A: ");
  148.    scanf("%lf",&A->VelocidadInicial);
  149.    printf("Introduce la aceleracion de A: ");
  150.    scanf("%lf",&A->aceleracion);
  151.    printf("Introduce la posicion inicial de B: ");
  152.    scanf("%lf",&B->PosicionInicial);
  153.    printf("Introduce la velocidad de B: ");
  154.    scanf("%lf",&B->VelocidadInicial);
  155.    printf("Introduce la aceleracion de B: ");
  156.    scanf("%lf",&B->aceleracion);
  157.    printf("\n");
  158. }
  159. //---------------------------------------------------------------------------
  160.  
  161. int main(int argc, char* argv[])
  162. {
  163.    int op,salir=0;
  164.    InfoObjeto A,B;
  165.    double t1,t2;
  166.  
  167.    do{
  168.       op=Menu();
  169.  
  170.       if(op > 0 && op <= 5){
  171.          switch(op){
  172.             case 1:
  173.                printf("\nMRUA al encuentro:\n");
  174.                printf("A---->Xf<----B\n\n");
  175.                ObtenerDatos(&A,&B);
  176.                B.PosicionInicial *= -1;
  177.                CalcularTiempos(&t1,&t2,A,B);
  178.                ReajustarDatos(&A,&B,positiva);
  179.                if(VerificarTiempo(t1,&A,&B) == 1)
  180.                   MostrarInfo(t1,A,B);
  181.                if(VerificarTiempo(t2,&A,&B) == 1)
  182.                   MostrarInfo(t2,A,B);
  183.                system("PAUSE");
  184.                system("CLS");
  185.                break;
  186.             case 2:
  187.                printf("\nMRUA al alcance:\n");
  188.                printf("A---->B---->Xf\n\n");
  189.                ObtenerDatos(&A,&B);
  190.                B.PosicionInicial *= -1;
  191.                B.VelocidadInicial *= -1;
  192.                B.aceleracion *= -1;
  193.                CalcularTiempos(&t1,&t2,A,B);
  194.                ReajustarDatos(&A,&B,positiva);
  195.                if(VerificarTiempo(t1,&A,&B) == 1)
  196.                   MostrarInfo(t1,A,B);
  197.                if(VerificarTiempo(t2,&A,&B) == 1)
  198.                   MostrarInfo(t2,A,B);
  199.                system("PAUSE");
  200.                system("CLS");
  201.                break;
  202.             case 3:
  203.                printf("\nMRUR al encuentro:\n");
  204.                printf("A---->Xf<----B\n\n");
  205.                ObtenerDatos(&A,&B);
  206.                B.PosicionInicial *= -1;
  207.                A.aceleracion *= -1;
  208.                B.aceleracion *= -1;
  209.                CalcularTiempos(&t1,&t2,A,B);
  210.                ReajustarDatos(&A,&B,negativa);
  211.                if(VerificarTiempo(t1,&A,&B) == 1)
  212.                   MostrarInfo(t1,A,B);
  213.                if(VerificarTiempo(t2,&A,&B) == 1)
  214.                   MostrarInfo(t2,A,B);
  215.                system("PAUSE");
  216.                system("CLS");
  217.                break;
  218.             case 4:
  219.                printf("\nMRUR al alcance:\n");
  220.                printf("A---->B---->Xf\n\n");
  221.                ObtenerDatos(&A,&B);
  222.                B.PosicionInicial *= -1;
  223.                B.VelocidadInicial *= -1;
  224.                A.aceleracion *= -1;
  225.                //B.aceleracion *= -1;
  226.                CalcularTiempos(&t1,&t2,A,B);
  227.                ReajustarDatos(&A,&B,negativa);
  228.                if(VerificarTiempo(t1,&A,&B) == 1)
  229.                   MostrarInfo(t1,A,B);
  230.                if(VerificarTiempo(t2,&A,&B) == 1)
  231.                   MostrarInfo(t2,A,B);
  232.                system("PAUSE");
  233.                system("CLS");
  234.                break;
  235.             case 5:
  236.                salir=1;
  237.                break;
  238.          }
  239.       }else{
  240.          printf("Opcion invalida. Vuelve a intentarlo.\n");
  241.       }
  242.    }while(salir != 1);
  243.  
  244.    return 0;
  245. }
  246. //---------------------------------------------------------------------------
¿que te parece la alternativa?

Etiquetas: alcance, funcion, nunca
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:59.