MyNameIsTrez

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)
  61.         self.vel = self.vel:add(self.acc)
  62.         self.pos = self.pos:add(self.vel)
  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