Last active
December 12, 2025 04:55
-
-
Save kevinkhill/2b85cbe86fad153ba0788f8eaae5e81d to your computer and use it in GitHub Desktop.
Giants Causeway Generator
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
| // Number of rows in the tessellation | |
| rows = 20; | |
| // Number of columns in the tessellation | |
| cols = 100; | |
| // Width of each hexagonal pillar (circumradius) | |
| hex_size = 4; | |
| // Minimum height of each pillar | |
| height_min = 2; | |
| // Maximum height of each pillar | |
| height_max = 20; | |
| // Desired number of sine wave periods across the grid width | |
| num_periods = 1.5; | |
| // Randomness to add to the height of the pillars | |
| jitter_factor = 5; | |
| // This determines where along the wave the heights start | |
| angle_tweak = -45; | |
| // Dynamically calculated amplitude | |
| wave_amplitude = (height_max - height_min); // Full range of heights | |
| // Function to calculate pillar height based on a sine wave (horizontal wave) | |
| function sine_height(col) = // | |
| let( // | |
| angle = col * PI * num_periods, // Map column to sine wave angle | |
| sine_value = sin(angle + angle_tweak), // Sine value (-1 to 1) | |
| scaled_sine = (sine_value * wave_amplitude) // Scale sine to desired amplitude | |
| ) // | |
| height_min | |
| + wave_amplitude + scaled_sine; // Offset to ensure range is height_min to height_max | |
| // Function to calculate row-based height factor (linear ramp from max to min) | |
| function row_factor(row) = 1 - row / (rows - 1); | |
| // Module for creating a hexagonal pillar | |
| module hexagon_pillar(width = 5, height = 3) | |
| { | |
| linear_extrude(height) | |
| { | |
| polygon(points = [[width * cos(0), width * sin(0)], // | |
| [width * cos(60), width * sin(60)], // | |
| [width * cos(120), width * sin(120)], // | |
| [width * cos(180), width * sin(180)], // | |
| [width * cos(240), width * sin(240)], // | |
| [width * cos(300), width * sin(300)]]); | |
| } | |
| } | |
| // Generate the tessellation | |
| for (row = [0:rows - 1]) | |
| { | |
| for (col = [0:cols - 1]) | |
| { | |
| // Calculate the x and y offsets for the hexagonal grid | |
| x_offset = col * 1.5 * hex_size; // Horizontal distance | |
| y_offset = row * sqrt(3) * hex_size + (col % 2) * (sqrt(3) * hex_size / 2); // Staggered rows | |
| // Calculate the combined height based on sine function and row factor | |
| height = sine_height(col) * row_factor(rows - row); | |
| // Add jitter for randomness | |
| jitter = rands(1, jitter_factor, 1)[0]; | |
| translate([ x_offset, y_offset, 0 ]) | |
| { | |
| hexagon_pillar(width = hex_size, height = (height_min + height + jitter)); | |
| } | |
| } | |
| } |
Author
Just want to point out that you can make a hexagon like this:
circle(d = hex_size, $fn = 6);
Author
Someone on reddit shared this with me too. I had no idea, and that's cool.
Is the sin call takes in degrees, rather than radians, what's the point of multiplying by PI on line 24?
Changing it to be angle = col / cols * num_periods and then doing sin(360 * angle + angle_tweak would mean you get definite control over the number of periods over the whole thing.
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment

YES! ...... how?