Ayuda con la programación en C (Segunda parte: Septiembre)

Aquí podrás hablar de cualquier cosa relacionada con la tecnología y la informática: software, hardware, internet, problemas con tu PC, robótica, I+D+i, etc.

Moderator: Viento

User avatar
will-o-the-wisp
Panacea Definitiva
Panacea Definitiva
Posts: 2466
Joined: 20 Dec 2009, 14:00
PSN ID: oh_mike_dog
Twitter: @oh_mike_god
Location: Zaragoza

Ayuda con la programación en C (Segunda parte: Septiembre)

Post by will-o-the-wisp » 31 Aug 2010, 11:39

El examen de prácticas consistirá en desarrollar el siguiente programa y hacer sobre él las modificaciones que los profesores estimen oportunas.

Sigo sin tener ni idea de programar en C, así que he intentado escribir algo como buenamente he podido. Escribo esto aquí porque no quiero tener esta asignatura de mierda el año que viene y para eso necesito que alguien me ayude, por favor :3

Veamos el enunciado:

Una partícula de masa 1 kg se mueve en el plano xy sometida a una fuerza dada por: F = - m*(ω_1^2*x*i + ω_2^2*y*j), (ω_1, ω_2 > 0). En el instante inicial, t = 0, la partícula se lanza desde la posición (x_0, y_0) con una velocidad inicial (v_x0, v_y0). Los datos del programa, que hay que introducir por teclado cada vez que se ejecuta son ω_1, ω_2 y la posición y velocidad iniciales (x_0, y_0), (v_x0, v_y0) (en m y m/s, respectivamente).

El programa debe (en el orden apropiado):

· Calcular, usando el algoritmo de LEAP-FROG, la posición (x,y) de la partícula en los instantes t = 0, 2dt, 4dt, 6dt, etc... hasta un tiempo máximo t_max, dado por teclado. dt es un pequeño intervalo fijo de tiempo que se dará por teclado (cuanto menor es dt más preciso y largo es el cálculo, en cualquier caso para que el algoritmo dé una solución correcta debe ser dt << 1/ω_1, 1/ω_2).

· Calcular la velocidad (v_x,v_y) de la partícula en los instantes t = dt, 3dt, 5dt, 7dt, etc... hasta el mismo tiempo máximo. Usar un algoritmo razonable para calcular la primera velocidad en el instante t = dt, ya que la velocidad inicial que se da es para t = 0.

· Escribir los resultados en un fichero de texto con 5 columnas que contengan los valores de t, x , y, v_x, v_y.

· Representar en pantalla x e y (en un sólo gráfico) en función de t con WGNUPLOT.

Definir de tipo DOUBLE todas las variables y constantes reales del programa.

Nota: el problema admite una solución analítica exacta pero se exigirá que el algoritmo empleado sea precisamente el de LEAP-FROG.

Seguro que, sepáis programación o no, habréis pensado "WTF?". Voy a explicar un poco la física del enunciado, que realmente eso lo tengo que saber yo.

La fuerza F = - m*(ω_1^2*x*i + ω_2^2*y*j) es un vector con dos componentes (en la dirección i y en la dirección j). Podríamos interpretarlo como un array bidimiensional, pero para lo que nos pide el problema (calcular las componentes x e y de la velocidad), podemos descomponer F = F_x*i + F_y*j y así podemos usar F_x y F_y independientemente (ahorrándonos bastante engorro).

El algoritmo de Leap-Frog es algo que nunca he entendido muy bien, pero he copiado literalmente en mi código fuente lo que sale en mis apuntes para un problema unidimensional. La cuestión sería hacerlo con la componente x y la componente y a la vez.

GNUPLOT es un programa que usamos para representar gráficas. Dudo mucho que alguien de por aquí sepa usarlo, pero no es eso lo que me preocupa. El programa puede funcionar perfectamente sin esa parte y buscarme luego yo la vida una vez tenga el resto (porque para ver si lo estoy usando bien necesito que el programa funcione).

Ahora bien, el código que tengo yo es:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

FILE *finput;

main()
{
/* Definición de variables */

     double x,y;             /* Posición */
     double x_0,y_0;         /* Posición inicial */
     double t,dt,t_max;      /* Tiempo */
     double om_1,om_2;       /* Frecuencia angular */
     double v_x,v_y;         /* Velocidad */
     double v_x0,v_y0;       /* Velocidad inicial */
     double dv_x,dv_y;       /* Diferencial de v */
     double m=1;             /* Masa */
     double f_x,f_y;         /* Fuerza */
     double F_x,F_y;
     double i;

/* Introducción por teclado */
 
     printf("Introduzca la frecuencia angular en el eje x:\n om_1 = ");
       scanf("%lf",&om_1); 
     printf("Introduzca la frecuencia angular en el eje y:\n om_2 = ");
       scanf("%lf",&om_2);
     printf("Introduzca la posici\xA2n inicial en el eje x:\n x_0 = ");
       scanf("%lf",&x_0);
     printf("Introduzca la posici\xA2n inicial en el eje y:\n y_0 = ");
       scanf("%lf",&y_0);
     printf("Introduzca la velocidad inicial en el eje x:\n v_x0 = ");
       scanf("%lf",&v_x0); 
     printf("Introduzca la velocidad inicial en el eje y:\n v_y0 = ");
       scanf("%lf",&v_y0);
     printf("Introduzca el tiempo m\xA0ximo:\n t_max = ");
       scanf("%lf",&t_max);
     printf("Introduzca el diferencial de tiempo:\n dt = ");
       scanf("%lf",&dt);
       if(dt>=1/om_1 & dt>1/om_2){
       printf("Introduzca un diferencial de tiempo menor:\n dt = ");
       scanf("%lf",&dt);
     
/* Datos en fichero */
     
     finput=fopen("datos.dat","w");
     
     /* Inicialización de variables */
     
     x=x_0;
     y=y_0;
     v_x=v_x0;
     v_y=v_y0;
     f_x=(-m)*x*om_1*om_1;
     f_y=(-m)*y*om_2*om_2;
     t=0;
     dv_x=f_x*dt/m;
     dv_y=f_y*dt/m;
     
     fprintf(finput,"t\t,x\t,y\t,v_x\t,v_y\t");
     
     /*Leapfrog*/
     
     for(i=0;i<=t_max;i=t+dt)
       {
       x=x+dt*v_x;
       y=y+dt*v_y;
       F_x=f_x;
       F_y=f_y;
       t=t+dt;
       dv_x+=f_x*dt/m;
       dv_y+=f_y*dt/m;
       v_x=v_x+dv_x;
       v_y+=dv_y;
       t=t+dt;
       fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
       }
     fclose(finput);
     }
     else
       {
       finput=fopen("datos.dat","w");
       x=x_0;
       y=y_0;
       v_x=v_x0;
       v_y=v_y0;
       f_x=(-m)*x*om_1*om_1;
       f_y=(-m)*y*om_2*om_2;
       t=0;
       fprintf(finput,"t\t,x\t,y\t,v_x\t,v_y\t\n");
       while(t<=t_max)
         {
         x=x+dt*v_x;
         y=y+dt*v_y;
         dv_x+=(f_x*dt)/m;
         dv_y+=(f_y*dt)/m;
         v_x=v_x+dv_x;
         v_y+=dv_y;
         fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
         t=t+dt;
         }
       fclose(finput);
       }
}



Que es lo mismo que no tener nada, pero vamos.

A ver si alguien me puede ayudar, aunque no sea con todo el programa. Muchísimas gracias.
Last edited by will-o-the-wisp on 01 Sep 2010, 17:27, edited 3 times in total.

User avatar
Kimhy
Gargán Dominante
Gargán Dominante
Posts: 3965
Joined: 25 Apr 2010, 10:32
PSN ID: Kimhy
Twitter: kimhymog

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Kimhy » 31 Aug 2010, 12:39

[center]Dios mío menos mal que no he estudiado "cosas de esas". Me parece realmente díficil, además no tengo ni idea. Los únicos símbolos "raros" que conozco son de HTML y CSS. XDDD Así que mira el "percal" que tengo. Siento contestar este mensaje con nada productivo, pero es que me parece tan raro todo lo que has escrito. XDD ¡Virgen del centollo divino![/center]
Image

User avatar
Pappapishu
Compañero de fatigas
Compañero de fatigas
Posts: 11986
Joined: 31 Jan 2010, 10:43
PSN ID: Pappaìshu
Twitter: @Pappapishu
STEAM: pappapishu
Location: Puerto Pollo, Isla Plunder
Contact:

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Pappapishu » 31 Aug 2010, 15:35

Bueno yo de C mucho no sé, de programación bastante y lo primero que te recomiendo es que no declares todas las variables en una misma línea.

Usa una línea para cada variable y al lado pon un comentario para indicar que información va a guardar cada variable, más que nada para que otra persona (yo por ejemplo) entienda para qué es cada cosa, y qué hace para poder ayudarte.

Lo de hacer el algoritmo con ambas a la vez te refies realmente a la vez? O una vez para cada variable por separado? En caso de tener que hacerlo a la vez te basta con copiar cualquier linea que contenga una X y sustituirla por Y.

Y de momento no sé que más decirte, con lo que veo no me aclaroXD
Image
https://www.instagram.com/madridwolvesqt/

User avatar
will-o-the-wisp
Panacea Definitiva
Panacea Definitiva
Posts: 2466
Joined: 20 Dec 2009, 14:00
PSN ID: oh_mike_dog
Twitter: @oh_mike_god
Location: Zaragoza

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by will-o-the-wisp » 31 Aug 2010, 18:03

Pappapishu wrote:Lo de hacer el algoritmo con ambas a la vez te refies realmente a la vez? O una vez para cada variable por separado? En caso de tener que hacerlo a la vez te basta con copiar cualquier linea que contenga una X y sustituirla por Y.

Sí, realmente pensaba en eso, pero el algoritmo que he copiado de los apuntes no sé si me sirve para lo que me piden.

Muchas gracias por contestar.

EDIT: He editado el código de arriba con más cosas. Ahora crea el archivo, pero falta todo el proceso anterior. Las variables las he agrupado en pequeños grupos, porque hay algunas como dt que no sé cómo denominar.

User avatar
will-o-the-wisp
Panacea Definitiva
Panacea Definitiva
Posts: 2466
Joined: 20 Dec 2009, 14:00
PSN ID: oh_mike_dog
Twitter: @oh_mike_god
Location: Zaragoza

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by will-o-the-wisp » 01 Sep 2010, 17:26

Vale, ya tengo el programa casi hecho. Para algunos valores se me desbordan los resultados en el archivo de texto, y no sé por qué:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

FILE *finput;

main()
{
/* Definición de variables */

     double x,y;             /* Posición */
     double x_0,y_0;         /* Posición inicial */
     double t,dt,t_max;      /* Tiempo */
     double om_1,om_2;       /* Frecuencia angular */
     double v_x,v_y;         /* Velocidad */
     double v_x0,v_y0;       /* Velocidad inicial */
     double dv_x,dv_y;       /* Diferencial de v */
     double m=1;             /* Masa */
     double f_x,f_y;         /* Fuerza */
     double F_x,F_y;
     double i;

/* Introducción por teclado */
 
     printf("Introduzca la frecuencia angular en el eje x:\n om_1 = ");
       scanf("%lf",&om_1); 
     printf("Introduzca la frecuencia angular en el eje y:\n om_2 = ");
       scanf("%lf",&om_2);
     printf("Introduzca la posici\xA2n inicial en el eje x:\n x_0 = ");
       scanf("%lf",&x_0);
     printf("Introduzca la posici\xA2n inicial en el eje y:\n y_0 = ");
       scanf("%lf",&y_0);
     printf("Introduzca la velocidad inicial en el eje x:\n v_x0 = ");
       scanf("%lf",&v_x0); 
     printf("Introduzca la velocidad inicial en el eje y:\n v_y0 = ");
       scanf("%lf",&v_y0);
     printf("Introduzca el tiempo m\xA0ximo:\n t_max = ");
       scanf("%lf",&t_max);
     printf("Introduzca el diferencial de tiempo:\n dt = ");
       scanf("%lf",&dt);
       if(dt>=1/om_1 & dt>1/om_2){
       printf("Introduzca un diferencial de tiempo menor:\n dt = ");
       scanf("%lf",&dt);
     
/* Datos en fichero */
     
     finput=fopen("datos.dat","w");
     
     /* Inicialización de variables */
     
     x=x_0;
     y=y_0;
     v_x=v_x0;
     v_y=v_y0;
     f_x=(-m)*x*om_1*om_1;
     f_y=(-m)*y*om_2*om_2;
     t=0;
     dv_x=f_x*dt/m;
     dv_y=f_y*dt/m;
     
     fprintf(finput,"t\t,x\t,y\t,v_x\t,v_y\t");
     
     /*Leapfrog*/
     
     for(i=0;i<=t_max;i=t+dt)
       {
       x=x+dt*v_x;
       y=y+dt*v_y;
       F_x=f_x;
       F_y=f_y;
       t=t+dt;
       dv_x+=f_x*dt/m;
       dv_y+=f_y*dt/m;
       v_x=v_x+dv_x;
       v_y+=dv_y;
       t=t+dt;
       fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
       }
     fclose(finput);
     }
     else
       {
       finput=fopen("datos.dat","w");
       x=x_0;
       y=y_0;
       v_x=v_x0;
       v_y=v_y0;
       f_x=(-m)*x*om_1*om_1;
       f_y=(-m)*y*om_2*om_2;
       t=0;
       fprintf(finput,"t\t,x\t,y\t,v_x\t,v_y\t\n");
       while(t<=t_max)
         {
         x=x+dt*v_x;
         y=y+dt*v_y;
         dv_x+=(f_x*dt)/m;
         dv_y+=(f_y*dt)/m;
         v_x=v_x+dv_x;
         v_y+=dv_y;
         fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
         t=t+dt;
         }
       fclose(finput);
       }
}

User avatar
Pappapishu
Compañero de fatigas
Compañero de fatigas
Posts: 11986
Joined: 31 Jan 2010, 10:43
PSN ID: Pappaìshu
Twitter: @Pappapishu
STEAM: pappapishu
Location: Puerto Pollo, Isla Plunder
Contact:

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Pappapishu » 01 Sep 2010, 17:49

una pregunta...el leapfrog...y el último bucle while...no hacen lo mismo???

Me parece muy bien como has separado las variables!
Image
https://www.instagram.com/madridwolvesqt/

User avatar
Black Flare
Plumaje Fénix
Plumaje Fénix
Posts: 796
Joined: 18 Jan 2010, 13:35
Location: Pitágoras.

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Black Flare » 01 Sep 2010, 18:28

En todo ese código ¿sólo calculas el Leap-frog?

Tampoco entiendo la función del if else que has puesto :S, supuestamente el if lo haces porque pones un valor dt demasiado grande ¿verdad?, después de eso vuelves a leer el valor de teclado y da igual el dato que pongas continúa el método o.O, (Sólo hace falta ver donde colocaste las llaves). Además ese if else te provoca que tengas que iniciar los datos dos veces.

El bucle for que hay bajo el leap-frog:

Code: Select all

for(i=0;i<=t_max;i=t+dt)
       {
       x=x+dt*v_x;
       y=y+dt*v_y;
       F_x=f_x;
       F_y=f_y;
       t=t+dt;
       dv_x+=f_x*dt/m;
       dv_y+=f_y*dt/m;
       v_x=v_x+dv_x;
       v_y+=dv_y;
       t=t+dt;
       fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
       }


Es una forma un tanto extraña de querer ver los instantes 0, 2td, 4td, porque realizas en medio dos sumas de dt a t, y luego ¿ese es el valor que adoptaría i?, enrevesado en mi opinión. Yo haría un cambio así:

Code: Select all

for(i=0;i<=t_max;i=i+2*dt)
       {
       x=x+dt*v_x;
       y=y+dt*v_y;
       F_x=f_x;
       F_y=f_y;
       dv_x+=f_x*dt/m;
       dv_y+=f_y*dt/m;
       v_x=v_x+dv_x;
       v_y+=dv_y;
       t = i;
       fprintf(finput,"%d\t,%d\t,%d\t,%d\t,%d\t\n",t,x,y,v_x,v_y);
       }


(Ahora que me fijo, una pregunta... ¿Para qué utilizas F_x y F_y?)

EDIT: Se me había pasado, con respecto al GNUPLOT... yo si lo he utilizado ya, para unas prácticas de redes en las que me cree un SCRIPT para mostrar gráficas de señales, no es lo mismo y al no tener idea del contenido y el formato de tus archivos no te voy a poder ser de mucha ayuda :S
Image

User avatar
will-o-the-wisp
Panacea Definitiva
Panacea Definitiva
Posts: 2466
Joined: 20 Dec 2009, 14:00
PSN ID: oh_mike_dog
Twitter: @oh_mike_god
Location: Zaragoza

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by will-o-the-wisp » 01 Sep 2010, 18:47

He mezclado lo que ya tenía hecho con los programas de dos compañeros míos, así que es muy probable que haya cometido alguna burrada en el proceso.

Ya me había dado cuenta de que el else no sirve de nada, porque introduciendo el mismo valor otra vez seguía funcionando, pero no sé cómo poner elses indefinidamente.

F_x y F_y estaban en una parte de las que he hecho copy-paste y había pensado que quizá eran una forma de guardar los valores iniciales de las funciones en otro lugar de la memoria. No sé si eso sirve de algo y hace bastante que le pregunté al autor, pero no me ha respondido aún xD

El for y el while del Leap-Frog creo que han surgido también de haber unido varias cosas, y ni me había dado cuenta de que son muy parecidos. Sin embargo no estoy seguro de que hagan lo mismo...

¡Muchas gracias a los dos!

EDIT: Lo de GNUPLOT se hace a partir del .dat que se genera, pero es independiente del código del programa.

User avatar
Black Flare
Plumaje Fénix
Plumaje Fénix
Posts: 796
Joined: 18 Jan 2010, 13:35
Location: Pitágoras.

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Black Flare » 01 Sep 2010, 19:07

Lo del GNUPLOT lo comento porque el script que me hice leía una señal en formato ascii almacenada en un fichero, cosa que no es lo mismo por lo que no te ayudaría.

Lo de que te vaya preguntando indefinidamente podría ser algo así:

Code: Select all

printf("Introduzca el diferencial de tiempo:\n dt = ");
scanf("%lf",&dt);

while(dt>=1) {
   printf("Introduzca un diferencial de tiempo menor:\n dt = ");
   scanf("%lf",&dt);
}


O una solución más amena.

Code: Select all

dt = 1;

while(dt>=1) {
   printf("Introduzca un diferencial de tiempo (Menor a 1) :\n dt = ");
   scanf("%lf",&dt);
}
Image

User avatar
Pappapishu
Compañero de fatigas
Compañero de fatigas
Posts: 11986
Joined: 31 Jan 2010, 10:43
PSN ID: Pappaìshu
Twitter: @Pappapishu
STEAM: pappapishu
Location: Puerto Pollo, Isla Plunder
Contact:

Re: Ayuda con la programación en C (Segunda parte: Septiembre)

Post by Pappapishu » 01 Sep 2010, 19:11

Sobre poner elses indefinidamente hay dos formas....poniendo una condicion en el else...es decir un else if:

if 1

else if 2

else if3

else


dejando el ultimo else sin condición

O usando un switch

swhitch(x)
1: print; break;
2: print; break;
3: print; break;
default: print;


segun el valor de x hace la linea del 1, 2, 3 o la por defecto
Image
https://www.instagram.com/madridwolvesqt/

Post Reply