Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active November 20, 2018 16:22
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/c4cedd8379042feda4c33f0c8d34ffbc to your computer and use it in GitHub Desktop.
Save JoshCheek/c4cedd8379042feda4c33f0c8d34ffbc to your computer and use it in GitHub Desktop.
Moire (w/ Matrices)
require 'graphics'
require 'matrix'
class Moire < Graphics::Simulation
include Math
def initialize(*args, distance:, radius:, frames_per_rotation:)
super *args
@fpr = frames_per_rotation
@radius = radius
@to_center = translate -w/2, -h/2
midpoint = Matrix[[w/2], [h/2], [1]]
canvas_radius = sqrt 2 * [w/2, h/2].min**2
num_dots = (2 * canvas_radius / distance).ceil
@points = num_dots.times.flat_map do |x|
num_dots.times.map do |y|
translate(x*distance-num_dots*distance/2, y*distance-num_dots*distance/2) * midpoint
end
end
end
def draw(n)
clear :white
transform = @to_center * rotate(n*2*PI/@fpr) * -@to_center
@points.each { |point| circle *xy(point), @radius, :black, :fill }
@points.each { |point| circle *xy(transform * point), @radius, :black, :fill }
end
def xy(point)
return point[0, 0], point[1, 0]
end
def translate(x, y)
Matrix[
[1, 0, x],
[0, 1, y],
[0, 0, 1],
]
end
def rotate(radians)
Matrix[
[cos(radians), -sin(radians), 0],
[sin(radians), cos(radians), 0],
[ 0, 0, 1],
]
end
end
Moire.new(500, 500, distance: 10, radius: 2, frames_per_rotation: 250).run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment