Last active
February 19, 2017 00:47
-
-
Save JoshCheek/13717ae35925f03c004113e631d14227 to your computer and use it in GitHub Desktop.
Fruit Flies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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