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