How to resolve the algorithm Babylonian spiral step by step in the Wren programming language
How to resolve the algorithm Babylonian spiral step by step in the Wren programming language
Table of Contents
Problem Statement
The Babylonian spiral is a sequence of points in the plane that are created so as to continuously minimally increase in vector length and minimally bend in vector direction, while always moving from point to point on strictly integral coordinates. Of the two criteria of length and angle, the length has priority. P(1) and P(2) are defined to be at (x = 0, y = 0) and (x = 0, y = 1). The first vector is from P(1) to P(2). It is vertical and of length 1. Note that the square of that length is 1. Next in sequence is the vector from P(2) to P(3). This should be the smallest distance to a point with integral (x, y) which is longer than the last vector (that is, 1). It should also bend clockwise more than zero radians, but otherwise to the least degree. The point chosen for P(3) that fits criteria is (x = 1, y = 2). Note the length of the vector from P(2) to P(3) is √2, which squared is 2. The lengths of the vectors thus determined can be given by a sorted list of possible sums of two integer squares, including 0 as a square. Find and show the first 40 (x, y) coordinates of the Babylonian spiral. Show in your program how to calculate and plot the first 10000 points in the sequence. Your result should look similar to the graph shown at the OEIS:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Babylonian spiral step by step in the Wren programming language
Source code in the wren programming language
import "dome" for Window
import "graphics" for Canvas, Color
import "./iterate" for Indexed, Stepped
import "./seq" for Lst
import "./fmt" for Fmt
import "./plot" for Axes
// Python modulo operator (not same as Wren's)
var pmod = Fn.new { |x, y| ((x % y) + y) % y }
var squareCache = []
"""
Get the points for each step along a Babylonian spiral of `nsteps` steps.
Origin is at (0, 0) with first step one unit in the positive direction along
the vertical (y) axis. The other points are selected to have integer x and y
coordinates, progressively concatenating the next longest vector with integer
x and y coordinates on the grid. The direction change of the new vector is
chosen to be nonzero and clockwise in a direction that minimizes the change
in direction from the previous vector.
See also: oeis.org/A256111, oeis.org/A297346, oeis.org/A297347
"""
var babylonianSpiral = Fn.new { |nsteps|
for (x in 0...nsteps) squareCache.add(x*x)
var dxys = [[0, 0], [0, 1]]
var dsq = 1
for (i in 0...nsteps) {
var x = dxys[-1][0]
var y = dxys[-1][1]
var theta = y.atan(x)
var candidates = []
while (candidates.isEmpty) {
dsq = dsq + 1
for (se in Indexed.new(squareCache)) {
var i = se.index
var a = se.value
if (a > (dsq/2).floor) break
for (j in dsq.sqrt.floor + 1...0) {
var b = squareCache[j]
if ((a + b) < dsq) break
if ((a + b) == dsq) {
candidates.addAll([ [i, j], [-i, j], [i, -j], [-i, -j],
[j, i], [-j, i], [j, -i], [-j, -i] ])
}
}
}
}
var comparer = Fn.new { |d| pmod.call(theta - d[1].atan(d[0]), Num.tau) }
candidates.sort { |a, b| comparer.call(a) < comparer.call(b) }
dxys.add(candidates[0])
}
var accs = []
var sumx = 0
var sumy = 0
for (dxy in dxys) {
sumx = sumx + dxy[0]
sumy = sumy + dxy[1]
accs.add([sumx, sumy])
}
return accs
}
// find first 10,000 points
var Points10000 = babylonianSpiral.call(9998) // first two added automatically
// print first 40 to terminal
System.print("The first 40 Babylonian spiral points are:")
for (chunk in Lst.chunks(Points10000[0..39], 10)) Fmt.print("$-9s", chunk)
class Main {
construct new() {
Window.title = "Babylonian spiral"
Canvas.resize(1000, 1000)
Window.resize(1000, 1000)
Canvas.cls(Color.white)
var axes = Axes.new(100, 900, 800, 800, -1000..11000, -5000..10000)
axes.draw(Color.black, 2)
var xMarks = Stepped.new(0..10000, 2000)
var yMarks = Stepped.new(-5000..10000, 5000)
axes.label(xMarks, yMarks, Color.black, 2, Color.black)
axes.line(-1000, 10000, 11000, 10000, Color.black, 2)
axes.line(11000, -5000, 11000, 10000, Color.black, 2)
axes.lineGraph(Points10000, Color.black, 2)
}
init() {}
update() {}
draw(alpha) {}
}
var Game = Main.new()
You may also check:How to resolve the algorithm Walk a directory/Recursively step by step in the Swift programming language
You may also check:How to resolve the algorithm Determinant and permanent step by step in the JavaScript programming language
You may also check:How to resolve the algorithm Image convolution step by step in the Mathematica / Wolfram Language programming language
You may also check:How to resolve the algorithm Introspection step by step in the R programming language
You may also check:How to resolve the algorithm Hash from two arrays step by step in the Oberon-2 programming language