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> |