Skip to content

Instantly share code, notes, and snippets.

@travisdoesmath
Created December 6, 2016 18:44
Show Gist options
  • Save travisdoesmath/3d56f08ac7e333d84aa943f2c781dbc3 to your computer and use it in GitHub Desktop.
Save travisdoesmath/3d56f08ac7e333d84aa943f2c781dbc3 to your computer and use it in GitHub Desktop.
Archimedean Ulam Spiral

What does it look like if we extend the idea behind Ulam's spiral and look at prime lengths of the Archimedean spiral?

Sadly, not like much.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.line {
fill: none;
stroke: red;
stroke-width: 1.5px;
}
.primePoint {
fill: blue;
stroke: none;
}
.compositePoint {
fill: none;
stroke: none;
}
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var width = 960,
height = 500,
radius = Math.min(width, height) / 2 - 30;
var nTurns = 25,
scaleFactor = 1;
var data = d3.range(0, 2 * nTurns * Math.PI, .01).map(function(t) {
return [t, t];
})
var r = d3.scaleLinear()
.domain([0, nTurns * 2 * Math.PI])
.range([0, radius])
var line = d3.radialLine()
.radius(function(d) { return r(d[1]); })
.angle(function(d) { return -d[0] + Math.PI / 2; });
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width * .5 + "," + height * .5 + ")");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
var spiralArcLength = function(theta) {
return 0.5 * (theta * Math.sqrt(1 + theta**2) + Math.log(theta + Math.sqrt(1 + theta**2)));
}
var spiralArcLengthDerivative = function(theta) {
return (1 + theta**2) / Math.sqrt(1 + theta**2);
}
var spiralInverseArcLength = function(length) {
length = length * scaleFactor;
var x = Math.sqrt(8*length + 5) * 0.5 - 0.5,
delta = Infinity,
precision = 0.0001;
while (Math.abs(delta) > precision) {
var newX = x - (spiralArcLength(x) - length)/spiralArcLengthDerivative(x);
delta = newX - x;
x = newX;
}
return x;
}
function isPrime(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
}
var totalSpiralLength = spiralArcLength(nTurns * Math.PI * 2);
points = d3.range(1, totalSpiralLength / scaleFactor, 1).map(function(t) {
var theta = spiralInverseArcLength(t);
return {"theta":theta, "radius": r(theta), "x":Math.cos(theta) * r(theta), "y": - Math.sin(theta) * r(theta), "n": t };
})
var circles = svg.selectAll("circle").data(points);
circles.enter().append("circle")
.attr("class", function(d) { if (isPrime(d.n)) { return "primePoint"; } else { return "compositePoint"; } })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", r(Math.log(nTurns) - 1));
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment