Modelado de un péndulo en C
math while-loop (5)
while(theta <2*PI&&-2*PI)
En
c
si queremos combinar expresiones múltiples, podemos combinarlas usando operadores lógicos comowhile((theta < 2 * PI) && (theta > -2 * PI))
PD- No soy un experto en física. Cambie las condiciones según su requisito
Este es mi código para intentar un while
Loop para modelar un swing de péndulo, sin embargo, los valores producidos no parecen ayudarme:
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
main()
{
float theta = 0; // initial value for angle
float omega = 0.2; // initial value for angular speed
float time = 0; // initial time
float dt = 0.01; // time step
while (theta < 2 * PI && -2*PI) {
time = time + dt;
theta = theta + omega*dt;
printf("theta=%i, omega=%i, time=%i, and dt=%i/n", theta, omega, time, dt);
}
system("PAUSE");
}
¿Cómo puedo modificar esto para ser más útil? La condición de tiempo que tengo que usar es que debe detenerse cuando el péndulo ha hecho una revelación, ya sea hacia adelante o hacia atrás (-2PI o 2PI). Necesito usar la fórmula ''omega = omega- (g / l) dt sin (theta)'' y NO hacer la suposición de que theta es aproximadamente igual a sin (theta).
La ecuación de ángulo que usa no es correcta. Según tu expresión, cambia linealmente con el tiempo, aunque la ecuación es armónica:
θ = θ 0 cos (ωt)
donde ω = g / L , L es la longitud del péndulo yg la aceleración debida a la gravedad.
Donde thetaMax
es el ángulo máximo de deflexión, g
es const de gravedad, L
es la longitud del péndulo t
es el tiempo. Por lo tanto, desea conocer thetaMax
de la ley de conservación de energía, por ejemplo.
Alrught, revisemos la ley de conservación de energía aquí:
Como saben, la energía potencial en la deflexión máxima es igual a la energía cinética en el punto más bajo de la trayectoria del péndulo:
KE = ПE
m*g*L*sin(thetaMax) = m*sqr(omega)*sqr(L)/2
Aproximadamente, para pequeños ángulos:
m*g*L*thetaMax = m*sqr(omega)*sqr(L)/2
thetaMax = sqr(omega)*L/(2*g)
eso es. Aquí hay un código que calcula este tipo de movimiento oscilatorio. Todos los valores absolutos:
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
#define L 1 //length of the pendulum
#define g 9.8 //gravity const
int main()
{
double theta = 0; // initial value for angle
double omega = 0.2; // initial value for angular speed
double time = 0; // initial time
double dt = 0.01; // time step
double thetaMax = omega*omega*L/(2*g);
while (theta < thetaMax) {
time = time + dt;
theta = thetaMax * sin(omega*time);
printf("theta=%f, omega=%f, time=%f, and thetaMax=%f/n", theta, omega, time, thetaMax);
}
return 0;
}
Va a calcular estos parámetros infinitamente, así que simplemente limite theta en la condición del ciclo while al ángulo de deflexión deseado.
La idea de modelar, en términos simples, implica encontrar una representación matemática de un fenómeno físico. En otras palabras, necesitas "encontrar" una ecuación que represente todas las propiedades observables del objeto en contexto, en tu caso un péndulo 1 .
Todo lo que necesitas para describir un péndulo es su ecuación de movimiento . Para encontrarlo primero debes tratar de calificar el movimiento, observándolo:
Si intenta desplazarlo (muchas veces con un ángulo muy pequeño) de su punto de equilibrio, observará en su mayoría pocos cambios a lo largo de la misma trayectoria, donde su amplitud disminuirá y volverá a su equilibrio estable, como si de algún modo se tratara. tipo de fuerza de restauración , en otras palabras, el péndulo realiza un movimiento regular y repetitivo, llamado movimiento periódico
Por lo tanto, estás buscando una función matemática que pueda representar un movimiento periódico, ya que resulta un gran candidato para este rol las funciones trigonométricas: sin y cos , que tienen la propiedad necesaria, es decir, se repiten con un punto T.
Para encontrar y cuantificar esta fuerza de restauración, utiliza la Segunda Ley de Newton, donde después de expresar todo en términos del ángulo muy pequeño theta << 1
(que permite el uso de la aproximación de ángulo pequeño: sin(theta) = theta
) del desplazamiento theta
, obtienes la ecuación de movimiento deseada, que está representada por la siguiente ecuación diferencial:
con una gran sorpresa (y con el primer orden de aproximación), cuando resuelves la ecuación anterior, encuentras:
que aproximadamente 2 coincide con las predicciones de sus observaciones (con algún error aleatorio (desviación estándar), preferiblemente no sistemático), es decir, el movimiento del péndulo se describe mediante la función coseno, tiene un movimiento periódico con una amplitud igual al desplazamiento inicial y un período igual a:
y aquí está la trampa ,
la ecuación anterior para theta
describe un péndulo que no pierde energía y sus valores se repiten infinitamente y es por eso que el bucle en su programa es un juego infinito de bucle infinitamente armónico con los mismos valores.
Si desea observar un movimiento que se detiene lentamente, necesita agregar una fuerza de amortiguación adicional que lentamente restará energía del sistema. Esta fuerza de amortiguación está representada por el siguiente término adicional en la ecuación de movimiento:
eso otra vez, se puede expresar en términos del ángulo theta
. Ahora, cuando resuelves la ecuación de movimiento, la amplitud se multiplica por:
donde b
es la constante de amortiguación de la que depende cuán rápido se detendrá el movimiento.
Como consecuencia de lo anterior ,
si quiere ver algo similar al péndulo real, necesita incluir este último exponencial en su ecuación.
Para hacer esto simplemente siga la gran explicación ofrecida por @Petr Stepanov, modificando thetaMax
para incluir el exponente anterior.
#include <stdio.h>
#include <math.h>
#define PI 3.14159
#define E 2.71828 // Euler''s number
#define L 1 // length of the pendulum
#define g 9.80665 // gravity const
int main() {
double theta = 0.0; // initial value for angle
double omega = 0.2; // initial value for angular speed
double time = 0.0; // initial time
double dt = 0.01; // time step
double b = 0.5; // modified damping constant
double thetaMax = omega * omega * L / (2 * g);
while (theta < thetaMax) {
time = time + dt;
theta = thetaMax * ldexp(E, (-b) * time) * sin(omega * time);
printf("Deflection angle=%f, Angular frequency=%f, Time=%f/n", theta, omega, time);
}
return 0;
}
1. Un objeto con masa m , colgado en un punto fijo con una rosca "sin masa" no elástica con una longitud l , que le permite oscilar libremente en un campo gravitacional, cuantificado por la constante de aceleración de la gravedad g .
2. Cabe señalar que: "todos los modelos son incorrectos, la pregunta práctica es qué tan incorrectos tienen que ser para no ser útiles"
La ecuación de un péndulo físico (simple, masa de punto en cuerda) es
θ '''' + k · sin (θ) = 0
donde la constante:
k = g / L
contiene gravedad gravitacional y longitud L.
θ
es el ángulo medido desde la posición de descanso, que por supuesto apunta hacia abajo, es decir, en un sistema de coordenadas cartesianas con la convención de ángulo usual, a -90 °. Por lo tanto, las oscilaciones del péndulo se traducen en oscilaciones theta
alrededor de cero.
Podrías resolver esa ecuación diferencial (conservadora) usando Euler simpléctico o Verlet / Leapfrog. Sylectico Euler en una variante tiene el ciclo (usando ω=θ''
, es decir, (θ'',ω'')=(ω, -k·sin(θ)
)
for(...) {
omega -= k*sin(theta) * dt;
theta += omega * dt;
t += dt;
printf(...);
}
Hay algunos problemas en este código:
De acuerdo con el estándar, no deberías usar
main()
Pero tampoco
-
int main()
-
int main(void)
-
int main(int argc, char *argv[])
También no olvides
return 0;
Programa de ejemplo:
#include <stdio.h> int main(void) { /* Do stuff */ return 0; }
Si desea leer más información al respecto, haga clic aquí .
-
Como LutzL señaló, debería usar
M_PI
lugar de su definición de PI. Solo#include <math.h>
Así es como imprimirías el valor, por ejemplo:
printf("/nValue of M_PI is %f/n/n", M_PI);
Lea más aquí .
Como lo señaló rootkea :
En c si queremos combinar expresiones múltiples, podemos combinarlas usando operadores lógicos como
while((theta < 2 * PI) && (theta > -2 * PI))
Si desea una mayor precisión (creo que este es el caso), debe utilizar el
double
lugar defloat
.Está intentando imprimir variables
float
con el especificador de formato"%i"
. Eso está mal,"%i"
se usa para imprimir entero con signo y usar el especificador incorrecto invoca comportamiento indefinido . Debería usar"%f"
para imprimir el punto flotante o el decimal doble con signo.
Lea sobre los especificadores de formato printf aquí .