D::i</~1-:0)?;{:}ak$2?X2 8?1]$#'~~\1?7 c?1$ '~~\?3 L
R:0)?/1-:̹{2,::}}-S{-2pS2p+'qA:{5,:}≮?/:}3,2*S:}S≯?/5,)?/]:̹{2,:}-S{-:̹'-A}'-A0)3*?P2?Z0]{{S:0)a*?:0(4*?~~10,'|A'aA{0)?S-:0≮4*?P2*+3*2P*%P)4*?'#2?' $]
Try it online!
Dear god. Why.
So much went wrong.
It makes me cry.
Several major impediments that ended up making this both (a) a nearly unreadable mess and (b) frustratingly difficult.
The first problem was the fact that Runic doesn't have atan2(x,y)
, so I had to heckin' work that out myself. And oh yeah, make sure its reasonably golfed, it had to be dropped into an existing program with no alterations, so in-line conditional logic was preferable.
The second problem was that I had a weird issue where I'd multiply the tangent value by 3, modulo to 2pi and get...nonsense. What even is that? Why is it not using angular values? Turned out I had a stray extra value at the bottom of the stack that was throwing the math off. Whoops.
THEN
AND THEN
The program would just suddenly die after the first four bytes of the outer wedges. Oh my, what fun we had. Lets simplify, shall we? Lets just isolate the inputs at that point and... oh. It works fine.
I.
Uh.
Hmm.
When in doubt, check the source code. Can you spot the difference?
Yep. Integer values are totes allowed to divide by zero (and return infinity) and doubles aren't. Oh and that's not even true in the original Unity C# code (which I use as a graphical debugger) as it was an intentional design decision to terminate on div-by-zero.
Wot. Also, conversion to float instead of double for no reason. Just sittin' there.
(╯°Д°)╯︵┻━┻
Explanation
I need a drink first.
That's better.
D::i< Set up the stack, we need a current position (X,Y) and total size. Init all to read value, counting down is easier than counting up.
The D here, and the R below it, constitute the main loop entry
R:0)?\1- Compare current X against zero, else decrement
\~1-:0)?;{:}ak$ if zero, decrement Y. If Y is zero, terminate, else return to the D on the first line (there's a lot of skip-over-logic)
:̹ {2,::}}-S{- dupe the entire stack, then translate origin by 1/2 width
2pS2p+'qA square root (x*x+y*y)
:{5,:}≮?\:}3,2*S:}S≯?\ compare that against 1/20th the width and 1.5/20th the width (R and 1.5R)
]$#'~~L $ '~~L Print # or <space> for the inner circle (and return to D) skip-bypasses omitted
5,)?/ Compare against 1/10th the width (5R), print a space and return to D
]:̹ {2,:}-S{-:̹ '-A}'-A0)3*?P2?Z0]{{S:0)a*?:0(4*?~~10,'|A'aA{0)?S- Dupe the entire stack and compute atan2(x,y)
:0≮4*?P2*+ Convert negative values to values greater than pi up to 2 pi
3*2P*%P)4*?'#2?' $] Multiply by 3, modulo 2pi, compare against pi. Less: print # else print space. Return to R.
Be wary of improperly stacking unicode combining characters. The little ̹
makes the command apply to the stack-of-stacks and ̸
is boolean-not; eg. ≮
is "not less than (aka greater-equals)." Looks like it costs bytes, but because of the upper line, there's a byte savings in that line being shorter, which pays for the +1 byte cost for an extended character in the lower line (typically assuming that the lower line could be ?!/
instead of ?/
).
n
such that the image has width2*n+1
? \$\endgroup\$