SHARE
TWEET

CC: Simple Planets Program

MyNameIsTrez May 30th, 2020 (edited) 1,660 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top