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 ?/
).
Can I take an input
n
such that the image has width2*n+1
? – Luis Mendo – 2019-11-23T18:50:27.397@LuisMendo Sure! – flawr – 2019-11-23T19:42:04.197
1Is it ok to return an integer matrix of 0s and 1s as the representation of the bitmap image? – Nick Kennedy – 2019-11-23T21:36:34.380
@NickKennedy That doesn't seem to be exaclty covered by the default I/O methods for image related challenges. So it's flawr's call
– Luis Mendo – 2019-11-23T23:42:39.790@LuisMendo I can make my program output a Netpbm file but it would cost 14 bytes to do so and feels unnecessary since it’s just prepending `P1 L L ‘ to the beginning where L is the length. But I agree, it’s flawr’s call. – Nick Kennedy – 2019-11-23T23:44:18.467
Can we write a function that takes x and y and returns the color at (x, y)? (one can pretend that's an array but with parentheses) – my pronoun is monicareinstate – 2019-11-24T01:25:38.427
2@NickKennedy I'd say a matrix just as a data type is not enough, but if it is printed nicely with two different characters as the "colours" (and no separators in between) it should be ok. – flawr – 2019-11-24T08:37:20.307
@mypronounismonicareinstate That is an interesting idea! Unfortunately I think that would change the answers in most languages so I say no fo rnow, but we should definitely reconsider this for [tag:graphical-output] challenges! As far as I understand this is more or less how pixelshaders work, right? – flawr – 2019-11-24T08:38:35.603
@flawr I'm pretty sure that's how they work (I'm not sure I understand the difference between pixel and fragment shaders well, but you might be referring to fragment shaders instead; but the difference is absolutely insignificant). – my pronoun is monicareinstate – 2019-11-24T08:48:20.000
1
@mypronounismonicareinstate I added the twos suggestions in the "defaults for IO" on meta, please vote. (1) (2)
– flawr – 2019-11-24T09:43:03.113