## Moire

```

using AbstractPlotting

function cartesian(ll)
return Point3f0(
cos(ll[1]) * sin(ll[2]),
sin(ll[1]) * sin(ll[2]),
cos(ll[2])
)
end
fract(x) = x - floor(x)
function calcpositions(rings, index, time, audio)
movement, radius, speed, spin = 1, 2, 3, 4;
position = Point3f0(0.0)
precision = 0.2f0
for ring in rings
position += ring[radius] * cartesian(
precision *
index *
Point2f0(ring[spin] + Point2f0(sin(time * ring[speed]), cos(time * ring[speed])) * ring[movement])
)
end
amplitude = audio[round(Int, clamp(fract(position[1] * 0.1), 0, 1) * (25000-1)) + 1]; # index * 0.002
position *= 1.0 + amplitude * 0.5;
position
end
rings = [(0.1f0, 1.0f0, 0.00001f0, Point2f0(0.2, 0.1)), (0.1f0, 0.0f0, 0.0002f0, Point2f0(0.052, 0.05))]
N2 = 25000
t_audio = sin.(range(0, stop = 10pi, length = N2)) .+ (cos.(range(-3, stop = 7pi, length = N2)) .* 0.6) .+ (rand(Float32, N2) .* 0.1) ./ 2f0
start = time()
t = (time() - start) * 100
pos = calcpositions.((rings,), 1:N2, t, (t_audio,))

scene = lines(
pos, color = RGBAf0.(to_colormap(:RdBu, N2), 0.6),
thickness = 0.6f0, show_axis = false, transparency = true
)
linesegments!(
scene, FRect3D(Vec3f0(-1.5), Vec3f0(3)), raw = true,
linewidth = 3, linestyle = :dot
)
eyepos = Vec3f0(5, 1.5, 0.5)
lookat = Vec3f0(0)
update_cam!(scene, eyepos, lookat)
scene.center = false # prevent scene from recentering on display
l = scene[1]
N = 150
record(scene, "output.mp4", 1:N) do i
t = (time() - start) * 700
pos .= calcpositions.((rings,), 1:N2, t, (t_audio,))
l[1] = pos # update argument 1
rotate_cam!(scene, 0.0, 0.01, 0.01)
end

```