-
-
Save timo/fe09badf375142c1a5d6b6d1ea950192 to your computer and use it in GitHub Desktop.
Terminal::Print example for a hilbert curve
This file contains 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
use Terminal::Print <T>; | |
use Terminal::Print::Pixelated; | |
my @colors = | |
(0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 0, 5), # Dark to bright blue | |
(1, 1, 5), (2, 2, 5), (3, 3, 5), (4, 4, 5), (5, 5, 5), # Light blue to white | |
(5, 5, 4), (5, 5, 3), (5, 5, 2), (5, 5, 1), (5, 5, 0), # Pale to bright yellow | |
(5, 4, 0), (5, 3, 0), (5, 2, 0), (5, 1, 0), (5, 0, 0), # Yellow-orange to red | |
(4, 0, 0), (3, 0, 0), (2, 0, 0), (1, 0, 0), (0, 0, 0); # Brick red to black | |
my @ramp = @colors.map: { ~(16 + 36 * .[0] + 6 * .[1] + .[2]) } | |
sub d2xy(int $n, int $d, int $x is rw, int $y is rw) { | |
my int $rx; | |
my int $ry; | |
my int $t = $d; | |
$x = 0; | |
$y = 0; | |
my int $s = 1; | |
#for 1, 2, 4 ... * >= $n -> int $s { | |
while $s < $n { | |
$rx = 1 +& ($t div 2); | |
$ry = 1 +& ($t +^ $rx); | |
rot $s, $x, $y, $rx, $ry; | |
$x += $s * $rx; | |
$y += $s * $ry; | |
$t div= 4; | |
$s *= 2; | |
} | |
} | |
sub rot(int $n, int $x is rw, int $y is rw, int $rx, int $ry) { | |
if $ry == 0 { | |
if $rx == 1 { | |
$x = $n - 1 - $x; | |
$y = $n - 1 - $y; | |
} | |
my int $t = $x; | |
$x = $y; | |
$y = $t | |
} | |
} | |
class HilbertFrame is Terminal::Print::FrameInfo { | |
has $.pixels; | |
} | |
class HilbertCrawl is Terminal::Print::PixelAnimation { | |
has @!hilbertcoords; | |
has @!pixels; | |
has $.size; | |
has $.pixels-set-up = 0; | |
has $!depth; | |
method setup { | |
$!size = (($.h * 2) min $.w) div 2; | |
@!pixels = ['' xx $.w] xx ($.h * 2); | |
$!depth = 2 ** ($!size.msb); | |
} | |
method stepcount { | |
($.size * 2) ** 2; | |
} | |
method compute-pixels() { | |
for $!pixels-set-up .. $.cur.pixels { | |
my int $x; | |
my int $y; | |
d2xy $!depth, $_, $x, $y; | |
@!pixels[$y][$x] = @ramp[($_ div 3) % *]; | |
#note $_; | |
} | |
$!pixels-set-up = $.cur.pixels; | |
@!pixels; | |
} | |
} | |
multi sub MAIN { | |
T.initialize-screen; | |
my $crawl = HilbertCrawl.new-from-grid(T.current-grid); | |
$crawl.setup; | |
for ^$crawl.stepcount { | |
$crawl.do-frame(HilbertFrame.new(:pixels($_))); | |
$crawl.composite; | |
} | |
sleep 1; | |
T.shutdown-screen; | |
} | |
multi sub MAIN("test") { | |
my @timings; | |
for ^10_000 { | |
my $t0 = now; | |
my int $x; | |
my int $y; | |
d2xy 64, $_, $x, $y; | |
@timings.push(now - $t0); | |
} | |
say @timings.fmt("%10f", "\n"); | |
} | |
#convert d to (x,y) | |
#void d2xy(int n, int d, int *x, int *y) { | |
#int rx, ry, s, t=d; | |
#*x = *y = 0; | |
#for (s=1; s<n; s*=2) { | |
#rx = 1 & (t/2); | |
#ry = 1 & (t ^ rx); | |
#rot(s, x, y, rx, ry); | |
#*x += s * rx; | |
#*y += s * ry; | |
#t /= 4; | |
#} | |
#} | |
#rotate/flip a quadrant appropriately | |
#void rot(int n, int *x, int *y, int rx, int ry) { | |
#if (ry == 0) { | |
#if (rx == 1) { | |
#*x = n-1 - *x; | |
#*y = n-1 - *y; | |
#} | |
#//Swap x and y | |
#int t = *x; | |
#*x = *y; | |
#*y = t; | |
#} | |
#} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment