Created
September 29, 2021 20:44
-
-
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.
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
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