Skip to content

Instantly share code, notes, and snippets.

@4hg
Created September 29, 2021 20:44
Show Gist options
  • Save 4hg/10c8f90cbde8caaa7931a28d6ddaa167 to your computer and use it in GitHub Desktop.
Save 4hg/10c8f90cbde8caaa7931a28d6ddaa167 to your computer and use it in GitHub Desktop.
Chaos game with a hexagon using the incenter of triangles for each step.
require 'ruby2d'
# origin is (320,240)
# Do not care to convert radians to degrees, 60 degrees = PI/3 radians
SIXTY_D = Math::PI / 3
def rotation_x(x, y, theta) = (x * Math.cos(theta)) - (y * Math.sin(theta))
def rotation_y(x, y, theta) = (x * Math.sin(theta)) + (y * Math.cos(theta))
def side_length(x1, y1, x2, y2) = Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
# incenter(*point, *hex[edge[0]], *hex[edge[1]])
def incenter(x1, y1, x2, y2, x3, y3)
a = side_length(x2, y2, x3, y3)
b = side_length(x1, y1, x3, y3)
c = side_length(x1, y1, x2, y2)
x = (a * x1 + b * x2 + c * x3) / (a + b + c)
y = (a * y1 + b * y2 + c * y3) / (a + b + c)
[x, y]
end
top_left = [rotation_x(0, 200, SIXTY_D) + 320, (rotation_y(0, 200, SIXTY_D) - 240).abs]
top_right = [rotation_x(0, 200, -SIXTY_D) + 320, (rotation_y(0, 200, -SIXTY_D) - 240).abs]
# Hex coord order is top, top-right, bottom-right, bottom, bottom-left, top-left
hex = [[320, 40], top_right,
[top_right[0], top_right[1] + 200], [320, 440],
[top_left[0], top_left[1] + 200], top_left]
edges = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]]
# The random starting point is chosen from within the interior rectangle of the hexagon
# as to avoid having to calculate if it is inside the hexagon and to allow for a random
# starting point
point = [rand((top_left[0]+1...top_right[0])), rand((top_left[1]+1...top_left[1]+200))]
# realistically only need around 3k iterations to show the shape
10_000.times do
v1, v2 = edges.sample
point = incenter(*point, *hex[v1], *hex[v2])
Circle.new(
x: point[0], y: point[1],
radius: 1
)
end
show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment