Skip to content

Instantly share code, notes, and snippets.

@lucatronica
Created February 27, 2020 23:02
Show Gist options
  • Save lucatronica/041441eef142c8de56457161bffebdac to your computer and use it in GitHub Desktop.
Save lucatronica/041441eef142c8de56457161bffebdac to your computer and use it in GitHub Desktop.
-- A note about faking toruses:
-- Spheres under projection become circles.
-- If we treat a torus like a chain of overlapping spheres, then we can draw
-- it using just circfill :)
::_::
cls(1)
-- The camera rotation angle.
q=t()/6
-- Two passes: first for the clouds, second for the rainbow.
for m=0,1 do
-- We'll use use m and c to 'remove' certail parts of expressions on each pass.
-- (Since multiplying by 0 will 'remove' them)
c=1-m
-- The rainbow requires two passes to make sure the rendering order is correct.
-- We want to render back to front. For the back half we want to do the outer
-- rings first, and for the front half we want to do the inner rings first.
for n=-1,1,2 do
-- Iterate the five rings, changing direction depending on the pass.
for j=2-n*2,2+n*2,n do
-- The radius of the ring.
-- The factor '7' was chosen since we don't want the rings to overlap
-- (there's a subtle render order issue if you choose less than 7).
r=22+j*7
-- Iterate across the arc of the ring (a is an angle).
for a=0,.5,.005 do
-- The position in the Z axis.
z=r*cos(a)*cos(q)
-- Depth scaling! We'll divide X and Y by this factor to get perspective.
-- Basic perspective explanation:
-- https://twitter.com/2DArray/status/1063509842592182273
k=1+z/150
-- This circfill is used for drawing both the clouds and the rainbow.
-- The clouds and the rainbow share X and Z positions.
-- But the Y position varies for the rainbow.
--
-- [sgn(z)==-n]:
-- For each pass we only want to draw one half of the arc.
-- If z is less than zero than we're in the back half of the arc.
-- So we can compare the sign of z to the n (-1 or +1) to do the limitting.
--
-- [sin(a)*c>-.4]:
-- For the cloud, we only want to draw the outer parts.
--
-- This line has been expanded from a single-line-if.
if sin(a)*c>-.4 and sgn(z)==-n then
circfill(
64+r*cos(a)*sin(q)/k,
64+(r*sin(a)*m+14+c*8)/k,
(3.5+c*4)/k,
7*c+m*(12-j)
)
end
end
end
end
end
flip()goto _
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment