Paul Liverman III 5 years ago
commit
7aa1e676de
3 changed files with 218 additions and 0 deletions
  1. 1
    0
      .gitignore
  2. 96
    0
      src/main.moon
  3. 121
    0
      src/old.moon

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
1
+*.lua

+ 96
- 0
src/main.moon View File

@@ -0,0 +1,96 @@
1
+width, height = love.graphics.getDimensions!
2
+radius = (width + height) / 4
3
+
4
+class Particle
5
+  new: (n=1, x, y, r=radius) =>
6
+    rng = love.math.newRandomGenerator n
7
+    @color = { rng\random!, rng\random!, rng\random!, 1 }
8
+    @mass = n
9
+    @charge = n % math.log(n)
10
+    @radius = math.log(n + 8)
11
+    if x and y
12
+      @x = x
13
+      @y = y
14
+    else
15
+      d = love.math.random! * r
16
+      r = love.math.random! * math.pi * 2
17
+      @x = d * math.sin r
18
+      @y = d * math.cos r
19
+    @vx = 0
20
+    @vy = 0
21
+
22
+universe = {}
23
+new = {}
24
+for i=1,800
25
+  table.insert universe, Particle nil, nil, nil, 200
26
+
27
+physics = (a, b) ->
28
+  dx = a.x - b.x
29
+  dy = a.y - b.y
30
+  d2 = dx * dx + dy * dy
31
+  theta = math.atan2 dy, dx
32
+  x = math.cos theta
33
+  y = math.sin theta
34
+  r2 = (a.radius + b.radius)^2
35
+  m = a.mass + b.mass
36
+  if d2 > r2
37
+    g = 1 / d2
38
+    a.vx -= b.mass * g * x
39
+    a.vy -= b.mass * g * y
40
+    b.vx += a.mass * g * x
41
+    b.vy += a.mass * g * y
42
+  -- elseif d2 < math.log(r2) / m^2
43
+  --   p = Particle m
44
+  --   p.vx = a.vx / a.mass + b.vx / b.mass
45
+  --   p.vy = a.vy / a.mass + b.vy / b.mass
46
+  --   p.x = (a.x * a.mass + b.x * b.mass) / m
47
+  --   p.y = (a.y * a.mass + b.y * b.mass) / m
48
+  --   a.dirty = true
49
+  --   b.dirty = true
50
+  --   table.insert new, p
51
+  else
52
+    f = math.min 1, 100 / math.max d2, 0.01
53
+    a.vx += f * x
54
+    a.vy += f * y
55
+    b.vx -= f * x
56
+    b.vy -= f * y
57
+    a.vx *= 0.99
58
+    a.vy *= 0.99
59
+    b.vx *= 0.99
60
+    b.vy *= 0.99
61
+    -- a.x += x
62
+    -- a.y += y
63
+    -- b.x -= x
64
+    -- b.y -= y
65
+
66
+love.update = (dt) ->
67
+  for a = 1, #universe - 1
68
+    for b = a + 1, #universe
69
+      physics(universe[a], universe[b])
70
+
71
+  for i = #universe, 1, -1
72
+    if universe[i].dirty
73
+      table.remove universe, i
74
+      i += 1
75
+
76
+  while next new
77
+    table.insert universe, table.remove new, 1
78
+
79
+  for particle in *universe
80
+    particle.x += particle.vx * dt
81
+    particle.y += particle.vy * dt
82
+
83
+love.mousepressed = (x, y) ->
84
+  for i = 1, 25
85
+    X = x - width / 2 + love.math.random -25, 25
86
+    Y = y - height / 2 + love.math.random -25, 25
87
+    table.insert universe, Particle 1, X, Y
88
+
89
+love.draw = ->
90
+  love.graphics.translate width / 2, height / 2
91
+  for particle in *universe
92
+    love.graphics.setColor particle.color
93
+    love.graphics.circle "fill", particle.x, particle.y, particle.radius
94
+
95
+love.keypressed = (key) ->
96
+  love.event.quit! if key == "escape"

+ 121
- 0
src/old.moon View File

@@ -0,0 +1,121 @@
1
+-- particle type influences attractive/repulsive forces
2
+-- heat
3
+width, height = love.graphics.getDimensions!
4
+clamp = (n, x, y) -> math.max x, math.min y, n
5
+sign = (n) -> math.abs(n) == n and 1 or -1
6
+
7
+class Particle
8
+  new: (n=1, x, y) =>
9
+    rng = love.math.newRandomGenerator n
10
+    @color = { rng\random!, rng\random!, rng\random!, 1 }
11
+    @mass = n
12
+    @charge = n % 5 - 2
13
+    @radius = math.log(n + 10)
14
+    @x = x or love.math.random 0, width
15
+    @y = y or love.math.random 0, height
16
+    @vx = 0
17
+    @vy = 0
18
+
19
+universe = {}
20
+new = {}
21
+for i=1,500
22
+  table.insert universe, Particle love.math.random 1, 5
23
+-- table.insert universe, Particle 1, width / 2 - 4, height / 2 - 200
24
+-- table.insert universe, Particle 5, width / 2 + 4, height / 2 - 200
25
+-- table.insert universe, Particle 1, width / 2 - 4, height / 2 + 200
26
+-- table.insert universe, Particle 1, width / 2 + 4, height / 2 + 200
27
+
28
+physics = (a, b) ->
29
+  -- distance, direction, collision checks
30
+  dx = a.x - b.x
31
+  dy = a.y - b.y
32
+  d2 = dx * dx + dy * dy
33
+  theta = math.atan2 dy, dx
34
+  x = math.cos theta
35
+  y = math.sin theta
36
+  r2 = (a.radius + b.radius)^2
37
+  m = a.mass + b.mass
38
+  if d2 > r2
39
+    -- gravitational force
40
+    g = 1 / d2
41
+    a.vx -= b.mass * g * x
42
+    a.vy -= b.mass * g * y
43
+    b.vx += a.mass * g * x
44
+    b.vy += a.mass * g * y
45
+    -- electromotive force
46
+    unless a.charge == 0 or b.charge == 0
47
+      e = (math.abs(a.charge) + math.abs(b.charge))^3 / d2^2
48
+      -- print a.charge, b.charge, e
49
+      if sign(a.charge) == sign(b.charge)
50
+        a.vx -= b.charge * e * x
51
+        a.vy -= b.charge * e * y
52
+        b.vx += a.charge * e * x
53
+        b.vy += a.charge * e * y
54
+      else
55
+        a.vx -= b.charge * e * x
56
+        a.vy -= b.charge * e * y
57
+        b.vx -= a.charge * e * x
58
+        b.vy -= a.charge * e * y
59
+  elseif d2 < math.log(r2) / m^3 / 10
60
+    -- making new elements
61
+    p = Particle m
62
+    p.vx = a.vx / a.mass + b.vx / b.mass
63
+    p.vy = a.vy / a.mass + b.vy / b.mass
64
+    p.x = (a.x * a.mass + b.x * b.mass) / m
65
+    p.y = (a.y * a.mass + b.y * b.mass) / m
66
+    a.dirty = true
67
+    b.dirty = true
68
+    table.insert new, p
69
+  else
70
+    -- anti-collision force
71
+    f = math.min 0.4, 100 / math.max d2, 0.01
72
+    a.vx += b.mass * f * x
73
+    a.vy += b.mass * f * y
74
+    b.vx -= a.mass * f * x
75
+    b.vy -= a.mass * f * y
76
+
77
+love.update = (dt) ->
78
+  for a = 1, #universe - 1
79
+    for b = a + 1, #universe
80
+      physics(universe[a], universe[b])
81
+
82
+  for i=#universe, 1, -1
83
+    if universe[i].dirty
84
+      table.remove universe, i
85
+      i += 1
86
+
87
+  while next new
88
+    table.insert universe, table.remove new, 1
89
+
90
+  for particle in *universe
91
+    -- particle.vx *= 0.9
92
+    -- particle.vy *= 0.9
93
+    particle.x += particle.vx * dt
94
+    particle.y += particle.vy * dt
95
+
96
+love.draw = ->
97
+  types = {}
98
+  for particle in *universe
99
+    if types[particle.mass]
100
+      types[particle.mass] += 1
101
+    else
102
+      types[particle.mass] = 1
103
+    love.graphics.setColor particle.color
104
+    love.graphics.circle "fill", particle.x, particle.y, particle.radius
105
+
106
+  -- love.graphics.setColor 1, 1, 1, 0.5
107
+  -- love.graphics.line width / 2, 0, width / 2, height
108
+  love.graphics.setColor 1, 1, 1, 1
109
+  love.graphics.print #universe
110
+  for i,v in ipairs types
111
+    love.graphics.print "#{i}->#{v}", 0, i * 12
112
+
113
+love.mousepressed = (x, y) ->
114
+  for i=1,50
115
+    a = x + love.math.random -25, 25
116
+    b = y + love.math.random -25, 25
117
+    table.insert universe, Particle 1, a, b
118
+
119
+love.keypressed = (key) ->
120
+  love.event.quit! if key == "escape"
121
+  table.insert universe, Particle!