# CC: Simple Planets Program

May 30th, 2020
1,933
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. -- CLASSES --------------------------------------------------------
2.
3. Particle = {
4.
5.     new = function(self, x, y, w, h, velMult, icon)
6.         local starting_values = {
7.             pos = vector.new(x, y),
8.             w = w,
9.             h = h,
10.             vel = vector.new(cf.randomFloat(-1 * velMult, 1 * velMult), cf.randomFloat(-1 * velMult, 1 * velMult)),
11.             icon = icon,
12.
13.             acc = vector.new(),
14.             mass = 10,
15.         }
16.         setmetatable(starting_values, {__index = self})
17.         return starting_values
18.     end,
19.
20.     show = function(self)
21.         shape.point(self.pos, self.icon) -- draw the particle
22.
23.         -- -- draw an arrow representing the velocity vector
24.         -- if (self.vel.x < -0.5) then
25.         --  local x = self.pos.x - 1
26.         --  if (x >= 1) then
27.         --      shape.point({x=x, y=self.pos.y}, "-")
28.         --  end
29.         -- elseif (self.vel.x > 0.5) then
30.         --  local x = self.pos.x + 1
31.         --  if (x <= self.w-1) then
32.         --      shape.point({x=x, y=self.pos.y}, "-")
33.         --  end
34.         -- end
35.
36.         -- if (self.vel.y < -0.5) then
37.         --  local y = self.pos.y - 1
38.         --  if (y >= 1) then
39.         --      shape.point({x=self.pos.x, y=y}, "|")
40.         --  end
41.         -- elseif (self.vel.y > 0.5) then
42.         --  local y = self.pos.y + 1
43.         --  if (y <= self.h-1) then
44.         --      shape.point({x=self.pos.x, y=y}, "|")
45.         --  end
46.         -- end
47.     end,
48.
49.     attracted = function(self, target, G, constraint)
50.         local force = target.pos:sub(self.pos) -- target.pos - self.pos
51.         local distanceSquared = cf.magSq(force)
52.         local strength = cf.clamp(G * ((self.mass * target.mass) / distanceSquared), 0, constraint)
53.
54.         force = force:normalize() -- normalizes the vector, so the hypotenuse is 1
55.         force = force:mul(strength)
56.
57.         self.acc = self.acc:add(force:mul(1/self.mass)) -- F = m * a, a = F / m, a = F * (1/m)
58.     end,
59.
60.     update = function(self)
63.     end
64.
65. }
66.
67. Attractor = {
68.
69.     new = function(self, x, y)
70.         local starting_values = {
71.             pos = vector.new(x, y),
72.             icon = "#",
73.             mass = 400,
74.         }
75.         setmetatable(starting_values, {__index = self})
76.         return starting_values
77.     end,
78.
79.     show = function(self)
80.         shape.point(self.pos, self.icon)
81.     end
82.
83. }
84.
85.
86.
87. -- FUNCTIONS --------------------------------------------------------
88.
89. function createParticles(n, x, y, w, h, velMult)
90.     local particles = {}
91.     for id = 1, n do
92.         local icon = string.char(32 + id) -- All chars except the space char.
93.         particles[#particles+1] = Particle:new(x, y, w, h, velMult, icon)
94.         -- particles[#particles+1] = Particle:new(math.random(w-1), math.random(h-1), w, h, velMult, icon)
95.     end
96.     return particles
97. end
98.
99. function createAttractors(n, w, h)
100.     local attractors = {}
101.     attractors[#attractors+1] = Attractor:new(w, h)
102.     return attractors
103. end
104.
105.
106.
107. -- CODE EXECUTION --------------------------------------------------------
108.
109. local G = 0.1
110. local constraint = 0.015
111. local particleCount = 5 -- 94 by default
112. local velMult = 0.1
113.
114. local w, h = term.getSize()
115. local particles = createParticles(particleCount, w/4, h/4, w, h, velMult)
116. local attractors = createAttractors(5, w/2, h/2)
117.
118. while true do
119.     if not rs.getInput(cfg.disableSide) then
120.         -- cf.clearTerm()
121.
122.         for i = 1, #particles do
123.             particle = particles[i]
124.
125.             for j = 1, #attractors do
126.                 attractor = attractors[j]
127.                 particle:attracted(attractor, G, constraint)
128.             end
129.
130.             particle:update()
131.
132.             local x = particle.pos.x
133.             local y = particle.pos.y
134.             local inCanvas = particle.pos.x >= 1 and particle.pos.x <= w and particle.pos.y >= 1 and particle.pos.y <= h
135.
136.             if inCanvas then
137.                 particle.icon = dithering.getClosestChar(cf.clamp(particle.vel:length() / 2, 0, 1))
138.                 particle:show()
139.             end
140.
141.             particle.acc = particle.acc:mul(0) -- reset the acceleration
142.         end
143.
144.         attractors[1]:show()
145.
146.         cf.tryYield()
147.         -- os.sleep(0.05)
148.     else
149.         sleep(1)
150.     end
151. end
RAW Paste Data