import taichi as ti
import math
ti.init()


@ti.data_oriented
class SolarSystem:
    def __init__(self, n, dt):
        # initializer of the solar system simulator
        self.n = n
        self.dt = dt
        self.x = ti.Vector.field(2, dtype=float, shape=n)
        self.v = ti.Vector.field(2, dtype=float, shape=n)
        self.center = ti.Vector.field(2, dtype=float, shape=())

    @staticmethod
    @ti.func
    def random_vector_in(rmax):
        # create a random vector
        a = ti.random() * math.tau
        r = ti.random() * rmax
        return r * ti.Vector([ti.cos(a), ti.sin(a)])

    @ti.kernel
    def initialize(self):
        # initialization or reset
        for i in range(self.n):
            offset = self.random_vector_in(0.5)
            self.x[i] = self.center[None] + offset  # Offset from center
            self.v[i] = [-offset.y, offset.x]  # Perpendicular to offset
            self.v[i] += self.random_vector_in(0.02)  # Shaking
            self.v[i] *= 1 / offset.norm()**1.5  # Kepler's 3rd law

    @ti.func
    def gravity(self, pos):
        # compute gravitational acceleration at pos
        offset = -(pos - self.center[None])
        return offset / offset.norm()**3

    @ti.kernel
    def integrate(self):
        # semi-implicit time integration
        for i in range(self.n):
            self.v[i] += self.dt * self.gravity(self.x[i])
            self.x[i] += self.dt * self.v[i]

    def render(self, gui):
        # render the simulation scene on the GUI
        gui.circle([0.5, 0.5], radius=10, color=0xffaa88)
        gui.circles(solar.x.to_numpy(), radius=3, color=0xffffff)


solar = SolarSystem(8, 0.0001)
solar.center[None] = [0.5, 0.5]
solar.initialize()

gui = ti.GUI("Solar System", background_color=0x0071a)

while gui.running:
    # GUI event processing
    if gui.get_event(gui.PRESS):
        if gui.event.key == gui.SPACE:
            solar.initialize()
        elif gui.event.key == gui.ESCAPE:
            gui.running = False

    for i in range(10):
        solar.integrate()

    solar.render(gui)
    gui.show()

@@ -25,16 +25,17 @@
 rt math%0A
+%0A
 ti.init(
@@ -105,28 +105,21 @@
  n, dt):
-%0A      
   # 
-i
+I
 nitializ
@@ -225,37 +225,38 @@
 .field(2, dtype=
-float
+ti.f32
 , shape=n)%0A     
@@ -284,37 +284,38 @@
 .field(2, dtype=
-float
+ti.f32
 , shape=n)%0A     
@@ -360,13 +360,14 @@
 ype=
-float
+ti.f32
 , sh
@@ -431,30 +431,22 @@
 ctor
-_in(rmax):%0A      
+(radius):
   # 
-c
+C
 reat
@@ -462,16 +462,26 @@
 m vector
+ in circle
 %0A       
@@ -481,16 +481,20 @@
         
+thet
 a = ti.r
@@ -506,17 +506,20 @@
 () *
+ 2 *
  math.
-tau
+pi
 %0A   
@@ -546,11 +546,13 @@
  * r
-max
+adius
 %0A   
@@ -585,16 +585,20 @@
 %5Bti.cos(
+thet
 a), ti.s
@@ -600,16 +600,20 @@
  ti.sin(
+thet
 a)%5D)%0A%0A  
@@ -643,16 +643,26 @@
 itialize
+_particles
 (self):%0A
@@ -671,16 +671,20 @@
       # 
+(Re)
 initiali
@@ -688,22 +688,38 @@
 aliz
-ation or reset
+e particle position/velocities
 %0A   
@@ -786,19 +786,16 @@
 m_vector
-_in
 (0.5)%0A  
@@ -981,19 +981,16 @@
 m_vector
-_in
 (0.02)  
@@ -995,15 +995,29 @@
   # 
-Shaking
+Random velocity noise
 %0A   
@@ -1073,17 +1073,19 @@
 epler's 
-3
+thi
 rd law%0A%0A
@@ -1128,20 +1128,13 @@
 os):
-%0A     
   
- 
 # 
-c
+C
 ompu
@@ -1146,28 +1146,9 @@
 avit
-ational acceleration
+y
  at 
@@ -1280,20 +1280,13 @@
 lf):
-%0A      
   # 
-s
+S
 emi-
@@ -1294,16 +1294,22 @@
 mplicit 
+Euler 
 time int
@@ -1484,20 +1484,13 @@
 ui):
-%0A     
   
- 
 # 
-r
+R
 ende
@@ -1499,19 +1499,8 @@
 the 
-simulation 
 scen
@@ -1504,20 +1504,16 @@
 cene on 
-the 
 GUI%0A    
@@ -1713,16 +1713,26 @@
 itialize
+_particles
 ()%0A%0Agui 
@@ -1782,17 +1782,16 @@
 x0071a)%0A
-%0A
 while gu
@@ -1809,92 +1809,46 @@
     
-# GUI event processing%0A    if gui.get_event(gui.PRESS):%0A        if gui.event.key == 
+if gui.get_event() and gui.is_pressed(
 gui.
@@ -1852,16 +1852,17 @@
 ui.SPACE
+)
 :%0A      
@@ -1859,28 +1859,24 @@
 E):%0A        
- 
-   
 solar.initia
@@ -1883,84 +1883,60 @@
 lize
-()%0A        elif gui.event.key == gui.ESCAPE:%0A            gui.running = False
+_particles()  # reinitialize when space bar pressed.
 %0A%0A  
@@ -1956,16 +1956,36 @@
 nge(10):
+  # Time integration
 %0A       

Update odop_solar (#1972)