Skip to content

Instantly share code, notes, and snippets.

Created February 17, 2017 18:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/7811e8681fecbfc661f453e0cadc44d1 to your computer and use it in GitHub Desktop.
Save anonymous/7811e8681fecbfc661f453e0cadc44d1 to your computer and use it in GitHub Desktop.
ulam-spiral
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ulam-spiral</title>
<script type="application/dart" src="main.dart"></script>
</head>
<body>
<h2>Ulam Spiral</h2>
<div>
<label>1</label>
<input id="slider" type="range" min="1" max="100" value="20" />
<label>100</label>
</div>
<div>
<canvas id="canvas" width="400" height="400"></canvas>
</div>
</body>
</html>
library ulamspiral;
import 'dart:html';
import 'dart:math' as math;
import 'dart:typed_data';
main() {
Uint8List mask = genMask(201 * 201);
new Ulam(mask);
}
Uint8List genMask(size) {
Uint8List res = new Uint8List(size);
for (var i=0; i < res.length; i++) {
res[i] = isPrime(i) ? 1 : 0;
}
return res;
}
bool isPrime(num n) {
if (n.isNaN || !n.isFinite || n % 1 != 0 || n < 2) return false;
if (n % 2 == 0) return (n == 2);
if (n % 3 == 0) return (n == 3);
var m = math.sqrt(n);
for (var i = 5; i <= m; i += 6) {
if (n % i == 0) return false;
if (n % (i + 2) == 0) return false;
}
return true;
}
class Ulam {
static const String ORANGE = "orange";
static const DOT_RADIUS = 1;
static const SCALE_FACTOR = 3;
static const TAU = math.PI * 2;
CanvasRenderingContext2D ctx;
num xc, yc;
num radius = 0;
Uint8List mask;
var dirs = [
[1, 0], // right
[0, 1], // down
[-1, 0], // left
[0, -1], // up
];
Ulam(this.mask) {
InputElement slider = querySelector("#slider");
slider.onChange.listen((Event e) {
build(slider.value);
});
build(slider.value);
}
void build(String value) {
CanvasElement canvas = querySelector("#canvas");
ctx = canvas.getContext("2d");
radius = int.parse(value);
canvas.width = canvas.height = (2 * radius + 1) * SCALE_FACTOR;
xc = yc = canvas.width / 2;
drawFrame();
}
Iterable<int> nextLen() sync* {
num i;
for (i=1; i < 1 + radius * 2; i++) {
yield i;
yield i;
}
yield i-1;
}
// Draw the complete figure for the current number of seeds.
void drawFrame() {
num dirIndex = 0;
var dir = dirs[dirIndex];
var x = 0;
var y = 0;
drawSeed(x * SCALE_FACTOR + xc,y * SCALE_FACTOR + yc, 'red');
var n = 0;
for (var len in nextLen()) {
for (var i=0; i<len; i++) {
x += dir[0];
y += dir[1];
n++;
if (mask[n] == 1) {
drawSeed(xc + x * SCALE_FACTOR, yc + y * SCALE_FACTOR, 'white');
}
}
dirIndex = ++dirIndex % 4;
dir = dirs[dirIndex];
}
}
// Draw a small circle representing a seed centered at (x,y).
void drawSeed(num x, num y, var color) {
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = color;
ctx.strokeStyle = color;
ctx.arc(x, y, DOT_RADIUS, 0, TAU, true);
ctx.fill();
ctx.closePath();
ctx.stroke();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment