1 #!/usr/bin/env python3
2 """ turtle-example-suite:
3
4 tdemo_planets_and_moon.py
5
6 Gravitational system simulation using the
7 approximation method from Feynman-lectures,
8 p.9-8, using turtlegraphics.
9
10 Example: heavy central body, light planet,
11 very light moon!
12 Planet has a circular orbit, moon a stable
13 orbit around the planet.
14
15 You can hold the movement temporarily by
16 pressing the left mouse button with the
17 mouse over the scrollbar of the canvas.
18
19 """
20 from turtle import Shape, Turtle, mainloop, Vec2D as Vec
21
22 G = 8
23
24 class ESC[4;38;5;81mGravSys(ESC[4;38;5;149mobject):
25 def __init__(self):
26 self.planets = []
27 self.t = 0
28 self.dt = 0.01
29 def init(self):
30 for p in self.planets:
31 p.init()
32 def start(self):
33 for i in range(10000):
34 self.t += self.dt
35 for p in self.planets:
36 p.step()
37
38 class ESC[4;38;5;81mStar(ESC[4;38;5;149mTurtle):
39 def __init__(self, m, x, v, gravSys, shape):
40 Turtle.__init__(self, shape=shape)
41 self.penup()
42 self.m = m
43 self.setpos(x)
44 self.v = v
45 gravSys.planets.append(self)
46 self.gravSys = gravSys
47 self.resizemode("user")
48 self.pendown()
49 def init(self):
50 dt = self.gravSys.dt
51 self.a = self.acc()
52 self.v = self.v + 0.5*dt*self.a
53 def acc(self):
54 a = Vec(0,0)
55 for planet in self.gravSys.planets:
56 if planet != self:
57 v = planet.pos()-self.pos()
58 a += (G*planet.m/abs(v)**3)*v
59 return a
60 def step(self):
61 dt = self.gravSys.dt
62 self.setpos(self.pos() + dt*self.v)
63 if self.gravSys.planets.index(self) != 0:
64 self.setheading(self.towards(self.gravSys.planets[0]))
65 self.a = self.acc()
66 self.v = self.v + dt*self.a
67
68 ## create compound yellow/blue turtleshape for planets
69
70 def main():
71 s = Turtle()
72 s.reset()
73 s.getscreen().tracer(0,0)
74 s.ht()
75 s.pu()
76 s.fd(6)
77 s.lt(90)
78 s.begin_poly()
79 s.circle(6, 180)
80 s.end_poly()
81 m1 = s.get_poly()
82 s.begin_poly()
83 s.circle(6,180)
84 s.end_poly()
85 m2 = s.get_poly()
86
87 planetshape = Shape("compound")
88 planetshape.addcomponent(m1,"orange")
89 planetshape.addcomponent(m2,"blue")
90 s.getscreen().register_shape("planet", planetshape)
91 s.getscreen().tracer(1,0)
92
93 ## setup gravitational system
94 gs = GravSys()
95 sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle")
96 sun.color("yellow")
97 sun.shapesize(1.8)
98 sun.pu()
99 earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet")
100 earth.pencolor("green")
101 earth.shapesize(0.8)
102 moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet")
103 moon.pencolor("blue")
104 moon.shapesize(0.5)
105 gs.init()
106 gs.start()
107 return "Done!"
108
109 if __name__ == '__main__':
110 main()
111 mainloop()