Skip to main content
Tweeted twitter.com/StackCodeReview/status/1223712725890752512
deleted 74 characters in body
Source Link

Herehere is my first project : I have made a double pendulum animation with tkinter on Python. Can you give me some feedback on what can be improved ? Thanks !

# General imports
import tkinter as tk
import random
import math as m

# Parameters
G = 9.81


class 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 = width


class 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.t = 0
        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.dt

    def 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
        self.canvas.create_line(self.trace_coords, fill='black', 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='pink', 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='pink', outline='pink', 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='pink', 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='pink', outline='pink', 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()

        # Next timestep
        self.t += self.dt

        # 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.pi

    pendulum_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()

Here is my first project : I have made a double pendulum animation with tkinter on Python. Can you give me some feedback on what can be improved ? Thanks !

# General imports
import tkinter as tk
import random
import math as m

# Parameters
G = 9.81


class 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 = width


class 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.t = 0
        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.dt

    def 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
        self.canvas.create_line(self.trace_coords, fill='black', 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='pink', 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='pink', outline='pink', 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='pink', 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='pink', outline='pink', 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()

        # Next timestep
        self.t += self.dt

        # 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.pi

    pendulum_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()

here is my first project : I have made a double pendulum animation with tkinter on Python. Can you give me some feedback on what can be improved ? Thanks !

# General imports
import tkinter as tk
import random
import math as m

# Parameters
G = 9.81


class 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 = width


class 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.dt

    def 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
        self.canvas.create_line(self.trace_coords, fill='black', 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='pink', 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='pink', outline='pink', 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='pink', 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='pink', outline='pink', 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.pi

    pendulum_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()
corrected introduction that disappeared
Source Link

Here is my first project : I have made a double pendulum animation with tkinertkinter on Python. Can you give me some feedback on what can be improved ? Thanks !

I have made a double pendulum animation with tkiner on Python. Can you give me some feedback on what can be improved ? Thanks !

Here is my first project : I have made a double pendulum animation with tkinter on Python. Can you give me some feedback on what can be improved ? Thanks !

Source Link

Double pendulum animation with tkinter

I have made a double pendulum animation with tkiner on Python. Can you give me some feedback on what can be improved ? Thanks !

Code :

# General imports
import tkinter as tk
import random
import math as m

# Parameters
G = 9.81


class 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 = width


class 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.t = 0
        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.dt

    def 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
        self.canvas.create_line(self.trace_coords, fill='black', 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='pink', 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='pink', outline='pink', 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='pink', 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='pink', outline='pink', 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()

        # Next timestep
        self.t += self.dt

        # 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.pi

    pendulum_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()