├── FUNDING.yml ├── README.md ├── __pycache__ ├── formular.cpython-37.pyc ├── formular.cpython-39.pyc ├── points.cpython-37.pyc └── points.cpython-39.pyc ├── formular.py ├── main.py └── points.py /FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: auctux 2 | ko_fi: auctux 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Double-Pendulum-with-Python-pygame 2 | 3 | ## Subscribe to my youtube channel 4 | https://www.youtube.com/channel/UCjPk9YDheKst1FlAf_KSpyA 5 | 6 | --- 7 | ### Commands 8 | "Esc" to close the window 9 | "R" to restart the simulation 10 | --- 11 | 12 | ![Screenshot (7)](https://user-images.githubusercontent.com/48150537/125934112-c71fe600-3b54-4655-be38-cbef9e3196b2.png) 13 | 14 | Enjoy✌️ 15 | -------------------------------------------------------------------------------- /__pycache__/formular.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/Double-Pendulum-with-Python-pygame/9633e65be98cce5c19b834e27a42ba8f6ec9d37a/__pycache__/formular.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/formular.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/Double-Pendulum-with-Python-pygame/9633e65be98cce5c19b834e27a42ba8f6ec9d37a/__pycache__/formular.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/points.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/Double-Pendulum-with-Python-pygame/9633e65be98cce5c19b834e27a42ba8f6ec9d37a/__pycache__/points.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/points.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/Double-Pendulum-with-Python-pygame/9633e65be98cce5c19b834e27a42ba8f6ec9d37a/__pycache__/points.cpython-39.pyc -------------------------------------------------------------------------------- /formular.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | """ 4 | v= velocity 5 | t = angle 6 | m = mass 7 | L = length 8 | G = gravity 9 | """ 10 | 11 | def FirstAcceleration(t1, t2, m1, m2, L1, L2, G, v1, v2): 12 | numerator1 = -G * (2 * m1 + m2) * math.sin(t1) 13 | numerator2 = -m2 * G * math.sin(t1 - 2 * t2) 14 | numerator3 = -2 * math.sin(t1-t2) 15 | numerator4 = m2 * ((v2 * v2) * L2 + (v1 * v1) * L1 * math.cos(t1-t2)) 16 | numerator = numerator1 + numerator2 + (numerator3 * numerator4) 17 | denominator = L1 * (2 * m1 + m2 - m2 * math.cos(2 * t1 - 2 * t2)) 18 | 19 | return float(numerator/denominator) 20 | 21 | def SecondAcceleration(t1, t2, m1, m2, L1, L2, G, v1, v2): 22 | numerator1 = 2 * math.sin(t1 - t2) 23 | numerator2 = (v1 * v1) * L1 * (m1 + m2) + G * (m1+ m2) * math.cos(t1) 24 | numerator3 = (v2 * v2) * L2 * m2 * math.cos(t1-t2) 25 | 26 | numerator = numerator1 * (numerator2 + numerator3) 27 | denominator = L2 * (2 * m1 + m2 - m2 * math.cos(2 * t1 - 2 * t2)) 28 | 29 | return float(numerator/denominator) 30 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import os 3 | import math 4 | import random 5 | from points import * 6 | import formular 7 | 8 | os.environ['SDL_VIDEO_CENTERED']='1' 9 | 10 | width, height = 1920, 1080 11 | SIZE = (width, height) 12 | pygame.init() 13 | pygame.display.set_caption("Double Pendulum") 14 | fps = 30 15 | screen = pygame.display.set_mode(SIZE) 16 | clock = pygame.time.Clock() 17 | 18 | 19 | mass1 = 40 20 | mass2 = 40 21 | length1 = 200 22 | length2 = 200 23 | 24 | angle1 = math.pi/2 25 | angle2 = math.pi/2 26 | angle_velocity1 = 0 27 | angle_velocity2 = 0 28 | angle_acceleration1 = 0 29 | angle_acceleration2 = 0 30 | Gravity = 8 31 | scatter1 = [] 32 | scatter2 = [] 33 | 34 | restart = False 35 | 36 | LIST_LIMIT = 100 37 | 38 | #COLORS 39 | BACKGROUND = (20, 20, 20) 40 | SCATTERLINE1 = (255, 255, 255) 41 | SCATTERLINE2 = (255, 255, 0) 42 | MAINPOINT = (0, 255, 0) 43 | SMALLPOINT = (0, 255, 255) 44 | PENDULUMARM = (45, 140, 245) 45 | ARMSTROKE = 10 46 | 47 | starting_point = (width//2 , height//3 ) 48 | 49 | x_offset = starting_point[0] 50 | y_offset = starting_point[1] 51 | 52 | run = True 53 | 54 | while run: 55 | clock.tick(fps) 56 | 57 | screen.fill(BACKGROUND) 58 | for event in pygame.event.get(): 59 | if event.type == pygame.QUIT: 60 | run = False 61 | if event.type == pygame.KEYDOWN: 62 | if event.key == pygame.K_ESCAPE: 63 | run = False 64 | if event.key == pygame.K_r: 65 | restart = True 66 | 67 | if restart == True: 68 | angle1 = math.pi/2 69 | angle2 = math.pi/2 70 | angle_velocity1 = 0 71 | angle_velocity2 = 0 72 | angle_acceleration1 = 0 73 | angle_acceleration2 = 0 74 | scatter1 = [] 75 | scatter2 = [] 76 | restart = False 77 | 78 | 79 | # calculate the acceleration 80 | angle_acceleration1 = formular.FirstAcceleration(angle1, angle2, mass1, mass2, length1, length2, Gravity, angle_velocity1, angle_velocity2) 81 | angle_acceleration2 = formular.SecondAcceleration(angle1, angle2, mass1, mass2, length1, length2, Gravity, angle_velocity1, angle_velocity2) 82 | 83 | x1 = float(length1 * math.sin(angle1)+x_offset) 84 | y1 = float(length1 * math.cos(angle1)+y_offset) 85 | 86 | x2 = float(x1 + length2 * math.sin(angle2)) 87 | y2 = float(y1 + length2 * math.cos(angle2)) 88 | 89 | # the angle varies with respect to the velocity and the velocity with respect to the acceleration 90 | angle_velocity1 += angle_acceleration1 91 | angle_velocity2 += angle_acceleration2 92 | angle1 += angle_velocity1 93 | angle2 += angle_velocity2 94 | 95 | scatter1.insert(0, (x1, y1)) 96 | scatter2.insert(0, (x2, y2)) 97 | #scatter1.append((x1, y1)) 98 | #scatter2.append((x2, y2)) 99 | 100 | 101 | for point in scatter2: 102 | random_color = (random.randint(20, 255), random.randint(20, 255), random.randint(20, 255)) 103 | plot = Points(point[0], point[1], screen, SCATTERLINE1, scatter2) 104 | plot.draw() 105 | 106 | if len(scatter1) > LIST_LIMIT: 107 | scatter1.pop() 108 | if len(scatter2) > LIST_LIMIT: 109 | scatter2.pop() 110 | 111 | pygame.draw.line(screen, PENDULUMARM, starting_point, (x1, y1), ARMSTROKE) 112 | pygame.draw.circle(screen, SMALLPOINT, starting_point, 8) 113 | 114 | if len(scatter1) > 1: 115 | pygame.draw.lines(screen, SCATTERLINE2, False, scatter1, 1) 116 | 117 | pygame.draw.line(screen, PENDULUMARM, (x1, y1), (x2, y2), ARMSTROKE) 118 | 119 | pygame.draw.circle(screen, SMALLPOINT, (int(x2), int(y2)), 10) 120 | pygame.draw.circle(screen, MAINPOINT, (int(x1), int(y1)), 20) 121 | 122 | pygame.display.update() 123 | 124 | pygame.quit() 125 | -------------------------------------------------------------------------------- /points.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | 3 | class Points: 4 | def __init__(self, x, y, surface,colors,coordinates): 5 | self.x = x 6 | self.y = y 7 | self.surface = surface 8 | self.colors = colors 9 | self.coordinates = coordinates 10 | def draw(self): 11 | if len(self.coordinates) > 2: 12 | pygame.draw.lines(self.surface, self.colors, False, self.coordinates, 4) 13 | --------------------------------------------------------------------------------