diff --git a/code/patterns/patterns_genbase.rb b/code/patterns/patterns_genbase.rb new file mode 100644 index 0000000..a6d4439 --- /dev/null +++ b/code/patterns/patterns_genbase.rb @@ -0,0 +1,62 @@ +require 'victor' + +BASE = 4 +DIRS = 7 + +def sum_digits(n) + x = n % BASE + x == 0 ? BASE : x +end + +def step(x, y, n, dir) + return [n*Math.cos(2*Math::PI/DIRS*dir), n*Math.sin(2*Math::PI/DIRS*dir), (dir+1) % DIRS] +end + +def run_number(number) + counter = 1 + x, y, dir = 0.0, 0.0, 0 + line_stack = [[0,0]] + + (BASE/BASE.gcd(number) * DIRS).times do |i| + dx, dy, dir = step(x,y, sum_digits(i*number), dir) + x += dx + y += dy + line_stack << [x,y] + end + + puts line_stack.to_s + return make_svg(line_stack) +end + +def make_svg(line_stack) + line_length = 20 + xs = line_stack.map { |c| c[0] } + ys = line_stack.map { |c| c[1] } + + x_offset = -xs.min + y_offset = -ys.min + svg_coords = ->(p) { + nx, ny = p + [(nx+x_offset)*line_length + line_length/2, (ny+y_offset)*line_length + line_length/2] + } + + max_width = (xs.max - xs.min).abs * line_length + line_length + max_height = (ys.max - ys.min).abs * line_length + line_length + svg = Victor::SVG.new width: max_width, height: max_height + + style = { stroke: 'black', stroke_width: 5 } + svg.build do + line_stack.each_cons(2) do |pair| + p1, p2 = pair + x1, y1 = svg_coords.call(p1) + x2, y2 = svg_coords.call(p2) + line x1: x1, y1: y1, x2: x2, y2: y2, style: style + circle cx: x2, cy: y2, r: line_length/6, style: style, fill: 'black' + end + end + return svg +end + +(1..10).each do |i| + run_number(i).save "pattern_#{i}" +end