Last active
February 16, 2017 04:24
-
-
Save JoshCheek/445fb5cda04b579305c59350fe0c1ca7 to your computer and use it in GitHub Desktop.
Writhing Electric Bezier
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/832083163220475905 | |
# You might need to already understand how bezier curves work to understand this. | |
# This one is probably a reasonable way to explore it: | |
# https://gist.github.com/JoshCheek/9139ff5f2764493a69675268e5e9556d | |
require "graphics" | |
class Integer | |
def of(obj) | |
times.map { obj } | |
end | |
end | |
class WritingElectricBezier < Graphics::Simulation | |
def initialize | |
super 500, 500*9/16, 24 | |
@derivations = 100 # in the calc sense | |
@length = 75 # how many points our line should have | |
@points = (@derivations + @length).times.map { rand_point } | |
color.default_proc = -> h, k { k } # so we don't have to rely on named colours | |
# Put white in there more times so since it has the most "electrifying" feel | |
@vibrant_colors = [:red, :green, :blue, :cyan, :magenta, :yellow, :black, *5.of(:white)] | |
end | |
def draw(iteration) | |
clear | |
# randomly swap out some of the points so the lines change across frames | |
rand(10).times do | |
idx = rand(@points.length) | |
@points[idx] = rand_point | |
end | |
# how many lines to draw | |
rand(8).times do |line_i| | |
# random distance along the bezier, leads to lines that are nearby but different | |
percentage = 0.5 + rand(-0.3..0.3) | |
# "derive" aka run out the iterations along the bezier curve | |
points = @derivations.times.reduce @points do |pts,*| | |
percentages_between pts, percentage | |
end | |
if line_i.zero? | |
# first line gets drawn thick and in one of the vibrant colors with | |
# a higher probability of being white | |
color = @vibrant_colors.sample | |
draw_lines_between points, color | |
next unless color == :white | |
draw_lines_between points.map { |x, y| [x-2, y] }, color | |
draw_lines_between points.map { |x, y| [x+1, y] }, color | |
draw_lines_between points.map { |x, y| [x, y-2] }, color | |
draw_lines_between points.map { |x, y| [x, y+1] }, color | |
else | |
# the rest of the lines are thinner and can appear anywhere on the color spectrum | |
draw_lines_between points, [rand(255), rand(255), rand(255)] | |
end | |
end | |
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(3*w)-w, rand(3*h)-h] | |
end | |
end | |
WritingElectricBezier.new.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment