Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active February 19, 2017 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/13717ae35925f03c004113e631d14227 to your computer and use it in GitHub Desktop.
Save JoshCheek/13717ae35925f03c004113e631d14227 to your computer and use it in GitHub Desktop.
Fruit Flies
# video https://twitter.com/josh_cheek/status/833115369267150848
require "graphics"
class FruitFlies < Graphics::Simulation
CLEAR_COLOR = [10, 21, 36]
def initialize
super 600, 350, 24
@points = 400.times.map { rand_point }
@delayed_draw = []
color.default_proc = -> h, k { k } # so we don't have to rely on named colours
end
def draw(ticks)
clear
# randomly swap out some of the points so the lines change across frames
rand(15).times do
idx = rand(@points.length)
@points[idx] = rand_point
end
end_clip = (@points.length*0.3).to_i
num_frames = @points.length-2*end_clip
color = [rand(255), rand(255), rand(255)]
if ticks % 5 == 1
points = @points
end_clip.times { points = percentages_between points, 0.5 }
num_frames.times do |i|
points = percentages_between points, 0.5
path_points = points.take(4)
dim_amt = 1-Math.sin(Math::PI*i/num_frames)
crnt_clr = dim(color, dim_amt)
(@delayed_draw[i] ||= []) << [dim_amt, lambda {
draw_lines_between path_points, crnt_clr
draw_lines_between path_points.map { |x, y| [x+1, y] }, crnt_clr
draw_lines_between path_points.map { |x, y| [x, y+1] }, crnt_clr
draw_lines_between path_points.map { |x, y| [x+2, y] }, crnt_clr
draw_lines_between path_points.map { |x, y| [x, y+2] }, crnt_clr
circle *path_points.last, 5, dim(white, dim_amt), true
}]
end
end
(@delayed_draw.shift||[])
.sort_by { |dim, _| dim } # draw dim ones first so they are in the bg
.each { |_, draw| draw.call } # draw the line
end
def mix((r1, g1, b1), (r2, g2, b2))
[(r1+r2)/2, (g1+g2)/2, (b1+b2)/2]
end
def white
@white ||= [255, 255, 255]
end
def dim((r, g, b), percent)
end_r, end_g, end_b = CLEAR_COLOR
[ r + (end_r-r)*percent,
g + (end_g-g)*percent,
b + (end_b-b)*percent,
]
end
def draw_lines_between(points, color)
points.each_cons 2 do |(x1, y1), (x2, y2)|
line x1, y1, x2, y2, color
end
end
# feels like if I think about calculus for a little bit, I might be able to
# come up with an equation for htis so that we don't have to repeatedly invoke it
def percentages_between(points, percent)
points.each_cons(2).map do |(x1, y1), (x2, y2)|
[x1+(x2-x1)*percent, y1+(y2-y1)*percent]
end
end
def rand_point
[rand(5*w)-2*w, rand(5*h)-2*h]
end
end
FruitFlies.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment