Babylonian spiral: Difference between revisions

m
→‎{{header|Wren}}: Made displayed image a bit smaller.
m (One line overflowed page width.)
m (→‎{{header|Wren}}: Made displayed image a bit smaller.)
 
(7 intermediate revisions by 3 users not shown)
Line 1:
{{task}}
f
 
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,
Line 168:
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.awt.Point;
import java.io.IOException;
Line 190 ⟶ 191:
}
System.out.println();
String text = svgText(points, 800);
Files.write(Paths.get("C:/Users/psnow/Desktop/BabylonianSpiralJava.svg"), text.getBytes());
}
private static List<Point> babylonianSpiral(int aStepCount) {
private static final double TAUtau = 2 * Math.PI;
List<Integer> squares = IntStream.rangeClosed(0, aStepCount).map( i -> i * i ).boxed().toList();
List<Point> deltaspoints = Stream.of( new Point(0, 0), new Point(0, 1) ).collect(Collectors.toList());
longint norm = 1;
for ( int step = 0; step < aStepCount - 2; step++ ) {
Point previousPoint = deltaspoints.get(deltaspoints.size() - 1);
final double theta = Math.atan2(previousPoint.y, previousPoint.x);
Set<Point> candidates = new HashSet<Point>();
Line 207 ⟶ 209:
norm += 1;
for ( int i = 0; i < aStepCount; i++ ) {
longint a = squares.get(i);
if ( a > norm / 2 ) {
break;
}
for ( int j = (int) Math.sqrt(norm) + 1; j >= 0; j-- ) {
longint b = squares.get(j);
if ( a + b < norm ) {
break;
Line 226 ⟶ 228:
Comparator<Point> comparatorPoint = (one, two) -> Double.compare(
( theta - Math.atan2(one.y, one.x) + TAUtau ) % TAUtau, ( theta - Math.atan2(two.y, two.x) + TAUtau ) % TAUtau);
Point minimum = candidates.stream().min(comparatorPoint).get();
deltaspoints.add(minimum);
}
for ( int i = 0; i < deltaspoints.size() - 1; i++ ) {
deltaspoints.set(i + 1, new Point(deltaspoints.get(i).x + deltaspoints.get(i + 1).x, deltaspoints.get(i).y + deltaspoints.get(i + 1).y));
}
return deltaspoints;
}
 
Line 252 ⟶ 254:
return text.toString();
}
private static final double TAU = 2 * Math.PI;
}
Line 485:
Plots.plot(babylonian_spiral(10_000))
</syntaxhighlight>
 
 
=={{header|MATLAB}}==
 
=== Directly translate Julia code ===
 
{{trans|Julia}}
<syntaxhighlight lang="MATLAB}}">
% Rosetta Code task rosettacode.org/wiki/Babylonian_spiral
 
clear all;close all;clc;
% Example usage
fprintf("The first 40 Babylonian spiral points are:\n");
spiral_points = babylonianspiral(40);
for i = 1:size(spiral_points, 1)
fprintf('(%d, %d) ', spiral_points(i, 1), spiral_points(i, 2));
if mod(i, 10) == 0
fprintf('\n');
end
end
 
% For plotting the spiral (requires MATLAB plotting functions)
spiral_points = babylonianspiral(10000);
plot(spiral_points(:, 1), spiral_points(:, 2), 'LineWidth', 1);
 
 
function points = babylonianspiral(nsteps)
% Get the points for 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.
% See also: oeis.org/A256111, oeis.org/A297346, oeis.org/A297347
persistent squarecache;
if isempty(squarecache)
squarecache = [];
end
 
if length(squarecache) <= nsteps
squarecache = [squarecache, arrayfun(@(x) x^2, length(squarecache):nsteps)];
end
 
xydeltas = [0, 0; 0, 1];
deltaSq = 1;
for i = 1:nsteps-2
x = xydeltas(end, 1);
y = xydeltas(end, 2);
theta = atan2(y, x);
candidates = [];
while isempty(candidates)
deltaSq = deltaSq + 1;
for k = 1:length(squarecache)
a = squarecache(k);
if a > deltaSq / 2
break;
end
for j = floor(sqrt(deltaSq)):-1:1
b = squarecache(j+1);
if a + b < deltaSq
break;
end
if a + b == deltaSq
i = k - 1;
candidates = [candidates; i, j; -i, j; i, -j; -i, -j; ...
j, i; -j, i; j, -i; -j, -i];
end
end
end
end
[~, idx] = min(arrayfun(@(n) mod(theta - atan2(candidates(n, 2), candidates(n, 1)), 2*pi), 1:size(candidates, 1)));
xydeltas = [xydeltas; candidates(idx, :)];
end
 
points = cumsum(xydeltas);
end
</syntaxhighlight>
{{out}}
<pre>
The first 40 Babylonian spiral points are:
(0, 0) (0, 1) (1, 2) (3, 2) (5, 1) (7, -1) (7, -4) (6, -7) (4, -10) (0, -10)
(-4, -9) (-7, -6) (-9, -2) (-9, 3) (-8, 8) (-6, 13) (-2, 17) (3, 20) (9, 20) (15, 19)
(21, 17) (26, 13) (29, 7) (29, 0) (28, -7) (24, -13) (17, -15) (10, -12) (4, -7) (4, 1)
(5, 9) (7, 17) (13, 23) (21, 26) (28, 21) (32, 13) (32, 4) (31, -5) (29, -14) (24, -22)
</pre>
 
[[File:BabylonianSpiral.png ]]
 
=={{header|Nim}}==
Line 1,018 ⟶ 1,102:
{{libheader|Wren-plot}}
Generates an image similar to the OEIS one.
<syntaxhighlight lang="ecmascriptwren">import "dome" for Window
import "graphics" for Canvas, Color
import "./iterate" for Indexed, Stepped
Line 1,122 ⟶ 1,206:
[5, 9] [7, 17] [13, 23] [21, 26] [28, 21] [32, 13] [32, 4] [31, -5] [29, -14] [24, -22]
</pre>
 
[[File:Wren-Babylonian_spiral.png|600px]]
9,476

edits