Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active January 11, 2016 15:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/7e14a5b173d8d6d9bf64 to your computer and use it in GitHub Desktop.
Save JoshCheek/7e14a5b173d8d6d9bf64 to your computer and use it in GitHub Desktop.
Freaky Dot Patterns, based on this video by Numberphile: https://www.youtube.com/watch?v=QAja2jp1VjE
# Pics at https://twitter.com/josh_cheek/status/681062928980783104
# Gif at https://twitter.com/josh_cheek/status/686465757476065280
# Based on https://www.youtube.com/watch?v=QAja2jp1VjE
require 'chunky_png'
require 'matrix'
include Math
def white
ChunkyPNG::Color.rgb(255, 255, 255)
end
def black
ChunkyPNG::Color.rgb( 0, 0, 0)
end
def rotate(point, a)
end
def point(x, y)
z = 0
Matrix[[x],[y],[z],[1]]
end
def draw(canvas, point)
x = point[0, 0].to_i
y = point[1, 0].to_i
radius = 2
stroke_colour = black
fill_colour = black
return unless canvas.include_xy? x, y
canvas.circle x, y, radius, stroke_colour, fill_colour
end
width = 800
height = 600
distance = 10
0.step(90, 3).with_index do |degrees, index|
canvas = ChunkyPNG::Canvas.new width*2, height*2, white
radians = degrees*Math::PI/180
# transformed
translation1 = Matrix[
[1,0,0, -width],
[0,1,0, -height],
[0,0,1, 0],
[0,0,1, 1],
]
rotation = Matrix[
[cos(radians) , -sin(radians) , 0 , 0],
[sin(radians) , cos(radians) , 0 , 0],
[0 , 0 , 1 , 0],
[0 , 0 , 0 , 1],
]
translation2 = Matrix[
[1,0,0, width],
[0,1,0, height],
[0,0,1, 0],
[0,0,1, 1],
]
transformation = translation2 * rotation * translation1
(width*2/distance).times do |x|
(height*2/distance).times do |y|
point = point(x*distance, y*distance)
draw canvas, point
draw canvas, (transformation*point)
end
end
canvas.save("rotated-#{index}.png")
end
`open .`
require 'erb'
num_cols = (ARGV[0]||'20').to_i
num_rows = (ARGV[1]||'20').to_i
radius = (ARGV[2]||'0.5').to_f
dot_colour = '#2A211c'
background_colour = '#FFFFFF'
dots_row = num_cols.times.map do |col|
x = 100.0*col/num_cols
'<use xlink:href="#dot" x="%0.2f" y="0"/>' % x
end.join("\n")
dots_grid = num_rows.times.map do |row|
y = 100.0*row/num_rows
'<use xlink:href="#dotsRow" x="0" y="%0.2f"/>' % y
end.join("\n")
puts ERB.new(DATA.read).result(binding)
__END__
<?xml version="1.0" encoding="utf-8"?>
<svg width = "800px"
height = "800px"
viewBox = "0 0 100 100"
version = "1.1"
xmlns = "http://www.w3.org/2000/svg"
xmlns:xlink = "http://www.w3.org/1999/xlink"
preserveAspectRatio = "xMidYMid"
baseProfile = "full"
>
<title>Dots</title>
<desc>Based on https://www.youtube.com/watch?v=QAja2jp1VjE</desc>
<defs>
<circle id="dot" cx="0" cy="0" r="<%= radius %>" stroke="black" stroke-width="0%" fill="<%= dot_colour %>" />
<g id="dotsRow" cx="0" cy="0"><%= dots_row %></g>
<g id="dotsGrid" cx="0" cy="0"><%= dots_grid %></g>
</defs>
<g>
<rect width="100" height="100" fill="<%= background_colour %>" />
<use xlink:href="#dotsGrid"/>
<g>
<use xlink:href="#dotsGrid"></use>
<animateTransform
attributeName = "transform"
type = "rotate"
from = "0 50 50"
to = "360 50 50"
begin = "0s"
dur = "60s"
repeatCount = "indefinite"
/>
</g>
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment