- This topic has 0 replies, 1 voice, and was last updated 2 years, 2 months ago by
Sahil Kumar.
-
AuthorPosts
-
-
May 26, 2020 at 10:49 am #534
Sahil Kumar
Moderatorhttps://github.com/ghostman-ai/Double_Pendulum.py.git
import tkinter as tk
import random
import math as m# Parameters
G = 9.81class Pendulum():
def __init__(self, theta: float, theta_dot: float,
mass: float, length: float,
width: int = 3):
“””Creates a Pendulum with a given position, velocity, length and mass.
width represent the width of the rope of the pendulum.
The size of the pendulum is proportional to its mass.”””self.theta = theta
self.theta_dot = theta_dot
self.mass = mass
self.length = length
self.width = widthclass App(tk.Tk):
def __init__(self,
pendulum_1: Pendulum, pendulum_2: Pendulum,
width: int = 600, height: int = 600,
offset_width: int = 300, offset_height: int = 120,
dt: float = 0.05):
“””Initialize the widget for the double pendulum animation.offset_width and offset_height represent the x and y offsets from the
top left corner of the canvas to place the first pendulum.”””# Setting attributes
self.width = width
self.height = height
self.offset_width = offset_width
self.offset_height = offset_height
self.dt = dt
self.pendulum_1 = pendulum_1
self.pendulum_2 = pendulum_2
self.trace_coords = []# Setting canvas widget
tk.Tk.__init__(self)
self.title(“Double Pendulum”)
self.canvas = tk.Canvas(self,
width=self.width, height=self.height)
self.canvas.pack(side=”top”)# Action
self.after(1, self.draw_frame)def update_pendulums_positions(self):
“””Update the angle positions and velocities of the two pendulums”””# Dealing with the first pendulum equation of motion
num_1 = -G * (2 * self.pendulum_1.mass + self.pendulum_2.mass)
num_1 *= m.sin(self.pendulum_1.theta)num_2 = -self.pendulum_2.mass * G
num_2 *= m.sin(
self.pendulum_1.theta –
2 * self.pendulum_2.theta
)num_3 = -2 * m.sin(self.pendulum_1.theta-self.pendulum_2.theta)
num_3 *= self.pendulum_2.mass
num_3 *= (
self.pendulum_2.theta_dot**2 * self.pendulum_2.length +
self.pendulum_1.theta_dot**2 * self.pendulum_1.length *
m.cos(
self.pendulum_1.theta –
self.pendulum_2.theta
)
)denom_1 = self.pendulum_1.length * (
2 * self.pendulum_1.mass +
self.pendulum_2.mass –
self.pendulum_2.mass *
m.cos(
2 * self.pendulum_1.theta –
2 * self.pendulum_2.theta
)
)# Dealing with the second pendulum equation of motion
num_4 = 2 * m.sin(self.pendulum_1.theta – self.pendulum_2.theta)
num_5 = (
self.pendulum_1.theta_dot**2 *
self.pendulum_1.length *
(self.pendulum_1.mass + self.pendulum_2.mass)
)num_6 = G * (self.pendulum_1.mass + self.pendulum_2.mass)
num_6 *= m.cos(self.pendulum_1.theta)num_7 = self.pendulum_2.theta_dot**2 * self.pendulum_2.length
num_7 *= self.pendulum_2.mass * m.cos(
self.pendulum_1.theta –
self.pendulum_2.theta
)denom_2 = self.pendulum_2.length * (
2 * self.pendulum_1.mass +
self.pendulum_2.mass –
self.pendulum_2.mass *
m.cos(
2 * self.pendulum_1.theta –
2 * self.pendulum_2.theta
)
)# Compute the accelerations
theta1_dotdot = (num_1 + num_2 + num_3) / denom_1
theta2_dotdot = (num_4*(num_5+num_6+num_7)) / denom_2# Update the velocities and positions
self.pendulum_1.theta_dot += theta1_dotdot * self.dt
self.pendulum_1.theta += self.pendulum_1.theta_dot * self.dt
self.pendulum_2.theta_dot += theta2_dotdot * self.dt
self.pendulum_2.theta += self.pendulum_2.theta_dot * self.dtdef draw_pendulums(self):
“””Draw the two pendulums and the trace”””# Cartesian coordinates
x1 = self.pendulum_1.length * m.sin(self.pendulum_1.theta)
y1 = self.pendulum_1.length * m.cos(self.pendulum_1.theta)x2 = x1 + self.pendulum_2.length * m.sin(self.pendulum_2.theta)
y2 = y1 + self.pendulum_2.length * m.cos(self.pendulum_2.theta)# Update the trace of the second pendulum
self.trace_coords.append(
(
self.offset_width + x2,
self.offset_height + y2,
self.offset_width + x2,
self.offset_height + y2
)
)# Draw the trace of second pendulum
self.canvas.create_line(self.trace_coords, fill=’red’, tag=’trace’)# Draw the first pendulum
self.canvas.create_line(
self.offset_width, self.offset_height,
self.offset_width + x1, self.offset_height + y1,
width=self.pendulum_1.width, fill=’purple’, tags=’pendulum’
)
self.canvas.create_oval(
self.offset_width – self.pendulum_1.mass + x1,
self.offset_height – self.pendulum_1.mass + y1,
self.offset_width + self.pendulum_1.mass + x1,
self.offset_height + self.pendulum_1.mass + y1,
fill=’blue’, outline=’black’, tags=’pendulum’
)# Draw the second pendulum
self.canvas.create_line(
self.offset_width + x1, self.offset_height + y1,
self.offset_width + x2, self.offset_height + y2,
width=self.pendulum_2.width, fill=’purple’, tags=’pendulum’
)
self.canvas.create_oval(
self.offset_width – self.pendulum_2.mass + x2,
self.offset_height – self.pendulum_2.mass + y2,
self.offset_width + self.pendulum_2.mass + x2,
self.offset_height + self.pendulum_2.mass + y2,
fill=’blue’, outline=’black’, tags=’pendulum’
)def draw_frame(self):
“””Draw the current frame”””# Delete objects on the canvas to redraw
self.canvas.delete(‘trace’)
self.canvas.delete(‘pendulum’)# Update the positions and draw the frame
self.update_pendulums_positions()
self.draw_pendulums()# Repeat
self.after(1, self.draw_frame)if __name__ == ‘__main__’:
# Initialization of the two pendulums
theta1 = random.random() * 2 * m.pi
theta2 = random.random() * 2 * m.pipendulum_1_parameters = {
“theta”: theta1,
“theta_dot”: 0,
“mass”: 10,
“length”: 100,
“width”: 3
}
pendulum_2_parameters = {
“theta”: theta2,
“theta_dot”: 0,
“mass”: 10,
“length”: 100,
“width”: 3
}pendulum_1 = Pendulum(**pendulum_1_parameters)
pendulum_2 = Pendulum(**pendulum_2_parameters)# Run the animation
animation_parameters = {
“pendulum_1”: pendulum_1,
“pendulum_2”: pendulum_2,
“width”: 600,
“height”: 600,
“offset_width”: 300,
“offset_height”: 150,
“dt”: 0.05
}
app = App(**animation_parameters)
app.mainloop()OUTPUT:
-
-
AuthorPosts
- You must be logged in to reply to this topic.