import numpy as np
import matplotlib.pyplot as plt
# Parameters
g = 9.81 # aceleración debido a la gravedad (m/s^2)
l1 = 0.24 # longitud del primer péndulo (m)
m1 = 1.5753 # masa del primer péndulo (kg)
l2 = 0.137 # longitud del segundo péndulo (m)
m2 = 0.5753 # masa del segundo péndulo (kg)
# Ángulos iniciales en grados
th10G = 90 # por ejemplo
th20G = -45 # por ejemplo
# Condiciones iniciales
th10 = np.radians(th10G) # ángulo inicial del primer péndulo (rad)
th20 = np.radians(th20G) # ángulo inicial del segundo péndulo (rad)
o10 = 0 # velocidad angular inicial del primer péndulo (rad/s)
o20 = 0 # velocidad angular inicial del segundo péndulo (rad/s)
# Time
t0 = 0
tf = 20
dt = 0.001 # paso de tiempo
t = np.arange(t0, tf, dt)
# Aceleración angular
def ac(o1, o2, th1, th2, l1, l2, m1, m2, g):
N1 = -g*(2*m1 + m2)*np.sin(th1) - m2*g*np.sin(th1 - 2*th2) - 2*m2*np.sin(th1 - th2)*(o2**2*l2 + o1**2*l1*np.cos(th1 - th2))
N2 = 2*np.sin(th1 - th2)*(o1**2*l1*(m1 + m2) + g*(m1 + m2)*np.cos(th1) + o2**2*l2*m2*np.cos(th1 - th2))
D1 = l1*(2*m1 + m2 - m2*np.cos(2*th1 - 2*th2))
D2 = l2*(2*m1 + m2 - m2*np.cos(2*th1 - 2*th2))
ao1 = N1/D1
ao2 = N2/D2
return ao1, ao2
def rk4(l1, l2, m1, m2, th10, th20, o10, o20, dt, t):
# Arrays to store solutions
th1 = np.zeros_like(t)
th2 = np.zeros_like(t)
o1 = np.zeros_like(t)
o2 = np.zeros_like(t)
# Seeds
th1[0] = th10
th2[0] = th20
o1[0] = o10
o2[0] = o20
# Solve the equations using the fourth-order Runge-Kutta method
for i in range(1, len(t)):
# Calculate intermediate increments for o1 and o2
ao1, ao2 = ac(o1[i-1], o2[i-1], th1[i-1], th2[i-1], l1, l2, m1, m2, g)
k1o1 = ao1*dt
k1o2 = ao2*dt
k1th1 = o1[i-1]*dt
k1th2 = o2[i-1]*dt
ao1, ao2 = ac(o1[i-1]+0.5*k1o1, o2[i-1]+0.5*k1o2, th1[i-1]+0.5*k1th1, th2[i-1]+0.5*k1th2, l1, l2, m1, m2, g)
k2o1 = ao1*dt
k2o2 = ao2*dt
k2th1 = (o1[i-1]+0.5*k1o1)*dt
k2th2 = (o2[i-1]+0.5*k1o2)*dt
ao1, ao2 = ac(o1[i-1]+0.5*k2o1, o2[i-1]+0.5*k2o2, th1[i-1]+0.5*k2th1, th2[i-1]+0.5*k2th2, l1, l2, m1, m2, g)
k3o1 = ao1*dt
k3o2 = ao2*dt
k3th1 = (o1[i-1]+0.5*k2o1)*dt
k3th2 = (o2[i-1]+0.5*k2o2)*dt
ao1, ao2 = ac(o1[i-1]+k3o1, o2[i-1]+k3o2, th1[i-1]+k3th1, th2[i-1]+k3th2, l1, l2, m1, m2, g)
k4o1 = ao1*dt
k4o2 = ao2*dt
k4th1 = (o1[i-1]+k3o1)*dt
k4th2 = (o2[i-1]+k3o2)*dt
# Update velocities and positions
o1[i] = o1[i-1] + (k1o1 + 2*k2o1 + 2*k3o1 + k4o1)/6
o2[i] = o2[i-1] + (k1o2 + 2*k2o2 + 2*k3o2 + k4o2)/6
th1[i] = th1[i-1] + (k1th1 + 2*k2th1 + 2*k3th1 + k4th1)/6
th2[i] = th2[i-1] + (k1th2 + 2*k2th2 + 2*k3th2 + k4th2)/6
# Return the additional results
return th1, th2, o1, o2, t
# Solve the equations using the fourth-order Runge-Kutta method
th1, th2, o1, o2, t = rk4(l1, l2, m1, m2, th10, th20, o10, o20, dt, t)
# Convert ángulos a coordenadas cartesianas
x1 = l1*np.sin(th1)
y1 = -l1*np.cos(th1)
x2 = x1 + l2*np.sin(th2)
y2 = y1 - l2*np.cos(th2)
# Graficar la trayectoria en el plano xy
plt.figure(figsize=(7, 6))
plt.plot(x2, y2, color='b')
plt.xlabel('$x (m)$', fontsize=12)
plt.ylabel('$y (m)$', fontsize=12)
plt.grid(True)
# Ajustar la escala para que sea real
plt.axis('equal')
plt.tight_layout()
plt.show()
# Plot of the angles as a function of time
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(t, th1, 'b-', linewidth=2)
plt.xlabel('$t\,(s)$', fontsize=12)
plt.ylabel('$\\theta_1 \, (rad)$', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
# Plot of the angles as a function of time
plt.subplot(1, 2, 2)
plt.plot(t, th2, 'r-', linewidth=2)
plt.xlabel('$t\,(s)$', fontsize=12)
plt.ylabel('$\\theta_2 \, (rad)$', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.tight_layout()
plt.show()
# Plot del espacio de fases
plt.figure(figsize=(12, 6))
# Espacio de fases para el primer péndulo
plt.subplot(1, 2, 1)
plt.plot(th1, o1, 'b-', linewidth=2)
plt.xlabel('$\\theta_1 \, (rad)$', fontsize=12)
plt.ylabel('$\\omega_1 \, (rad/s)$', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
# Espacio de fases para el segundo péndulo
plt.subplot(1, 2, 2)
plt.plot(th2, o2, 'r-', linewidth=2)
plt.xlabel('$\\theta_2 \, (rad)$', fontsize=12)
plt.ylabel('$\\omega_2 \, (rad/s)$', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.tight_layout()
plt.show()
# Graficar resultados
plt.figure(figsize=(8, 6))
plt.plot(th1,th2,'r-', linewidth=2)
plt.xlabel('$\\theta_1 \, (rad)$', fontsize=12)
plt.ylabel('$\\theta_2 \, (rad)$', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.tight_layout()
plt.show()
# Construcción de la sección de Poincaré
# Define el plano de corte para la sección de Poincaré
cut_angle = 0 # por ejemplo, ángulo de corte en theta1 = 0 rad
# Identificar las intersecciones de las trayectorias con el plano de corte
poincare_points = []
for i in range(1, len(th1)):
if (th1[i-1] < cut_angle and th1[i] >= cut_angle) or (th1[i-1] > cut_angle and th1[i] <= cut_angle):
poincare_points.append((th2[i], o2[i]))
# Convertir los puntos de Poincaré a un array para facilidad de uso en gráficos
poincare_points = np.array(poincare_points)
# Graficar la sección de Poincaré
plt.figure(figsize=(8, 6))
plt.plot(poincare_points[:, 0], poincare_points[:, 1], 'bo', markersize=2)
plt.xlabel('$\\theta_2$ (rad)', fontsize=12)
plt.ylabel('$\\omega_2$ (rad/s)', fontsize=12)
plt.grid(True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.tight_layout()
plt.show()
To embed this project on your website, copy the following code and paste it into your website's HTML: