Created
January 10, 2019 09:36
-
-
Save monkstone/77b95a422a58974ea2af95cd0b7b0aab to your computer and use it in GitHub Desktop.
Recursive Pentagons
This file contains hidden or 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
attr_reader :strut_factor, :renderer | |
MAX_LEVEL = 5 | |
def setup | |
sketch_title 'Recursive Fractals' | |
@strut_factor = 0.2 | |
@renderer = AppRender.new self # so we can send Vec2D :to_vertex | |
background(255) | |
no_loop | |
end | |
def draw | |
translate(width / 2, height / 2) | |
angle = TWO_PI / 5 | |
radius = width / 2 | |
points = (0...5).map do |i| | |
x = radius * cos(angle * i) | |
y = radius * sin(angle * i) | |
Vec2D.new(x, y) | |
end | |
fractal = Fractal.new(Pentagon.new(1, points)) | |
fractal.draw | |
end | |
def settings | |
size(800, 800) | |
end | |
class Pentagon | |
attr_reader :level, :points, :weight | |
def initialize(level, points) | |
@level = level | |
@points = points | |
@weight = [0.5, 1, 3, 5].sample | |
end | |
def draw | |
no_fill | |
begin_shape | |
stroke_weight weight | |
points.each do |point| | |
point.to_vertex(renderer) | |
end | |
end_shape CLOSE | |
end | |
end | |
# Here we include Processing::Proxy to mimic vanilla processing inner class | |
# access. | |
class Fractal | |
include Processing::Proxy | |
attr_reader :pentagon ,:branches, :midpoints, :innerpoints | |
def initialize(pentagon) | |
@pentagon = pentagon | |
points = pentagon.points | |
return if pentagon.level == MAX_LEVEL | |
# find the midpoints on each edge | |
@midpoints = (0...5).map do |i| | |
midpoint(points[i], points[(i + 1) % 5]) | |
end | |
# find the inner points | |
@innerpoints = (0...5).map do |i| | |
opposite = points[(i + 3) % 5] | |
x = midpoints[i].x + (opposite.x - midpoints[i].x) * strut_factor | |
y = midpoints[i].y + (opposite.y - midpoints[i].y) * strut_factor | |
Vec2D.new(x, y) | |
end | |
# Create the Pentagon objects representing the six inner | |
# Pentagons | |
# the shape is very regular, so we can build the ring of five | |
@branches = (0...5).map do |i| | |
p = [ | |
midpoints[i], | |
innerpoints[i], | |
innerpoints[(i + 1) % 5], | |
midpoints[(i + 1) % 5], | |
points[(i + 1) % 5] | |
] | |
Fractal.new(Pentagon.new(pentagon.level + 1, p)) | |
end | |
# add the final innermost Fractal | |
branches << Fractal.new(Pentagon.new(pentagon.level + 1, innerpoints)) | |
end | |
# This is a simple helper function that takes in two points (as Vec2D) and | |
# returns the midpoint between them as Vec2D. | |
def midpoint(point1, point2) | |
(point2 + point1) * 0.5 | |
end | |
# This draws the fractal. If this is on level 0, we just draw the | |
# Fractal formed by the points. When not level 0, iterate through the | |
# six branches and tell them to draw themselves. | |
def draw | |
branches.each do |branch| | |
break if branch.pentagon.level == MAX_LEVEL | |
branch.pentagon.draw | |
branch.draw | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment