# Draw the Archimedean Spiral

## Overview

I was playing with Desmos and discovered a really cool spiral:

Doing some research, I discovered that this spiral was the Archimedian spiral. Every point on the spiral is exactly $$\\theta\$$ away from the origin, where $$\\theta\$$ is the angle from the origin. That is, any point on the spiral has the polar coordinates $$\(\theta, \theta)\$$. This also has the consequence that the shortest distance between 2 arms of the spiral is exactly $$\2\pi\$$ if using radians or $$\360\$$ if using degrees.

## The Challenge

The basic spiral can be defined by the following formula in the polar coordinate system: $$r = a\theta$$ Where $$\a\$$ is the multiplier of the distance between the arms. Your job is, given a floating point input for $$\a\$$, draw this spiral with at least one full rotation. You may output the image according to any image I/O defaults.

## Scoring

This is , shortest answer in bytes wins.

• You may use either degrees or radians for $\theta$, but not anything else. Does it really matter? Unless we are required to draw the axis and make the scale explicit, this looks like a non-observable requirement. May 13, 2022 at 17:47
• @Arnauld I guess that's a fair point May 13, 2022 at 18:07

# Minecraft Command Blocks, 599 bytes

## Commands

Left column (bottom block 0, 4, -2)

scoreboard objectives add c dummy
scoreboard players set m c 1
summon armor_stand 0 0 0
setblock 0 3 0 redstone_block


Middle column (bottom block 0, 4, 0)

execute at @e[type=armor_stand] run setblock ~ ~ ~ stone
tp @e[type=armor_stand] 0 0 0
execute as @e[type=armor_stand] at @s run tp @s ~ ~ ~ ~5 ~
scoreboard players reset d
scoreboard players add m c 1
setblock 0 3 1 air
setblock 0 3 1 redstone_block


Right column (bottom block 0, 4, 1)

execute as @e[type=armor_stand] at @s run tp @s ^ ^ ^<Input>
scoreboard players add d c 1
setblock 0 3 1 air
setblock 0 3 0 air
execute unless score d c = m c run setblock 0 3 1 redstone_block
execute if score d c = m c run setblock 0 3 0 redstone_block


The distance multiplier is set in the first command block in the right column. Hardcoding inputs is not allowed by codegolf rules, but there isn't any other way to take input in Minecraft.

When ran for an hour with an input of 0.1 it produced this. It starts skipping blocks after a little over one rotation but it does complete one full rotation.

• does tp @s ^ ^ ^<Input> cause the armour stand to rotate? May 16, 2022 at 8:58
• Nice one! Minecraft answers seem to be so rare in CGCC. May 16, 2022 at 15:33
• @user253751 tp @s ^ ^ ^<Input> teleports the armor stand <Input> blocks in the direction it's facing. tp @s ~ ~ ~ ~5 ~ is the command that rotates it. May 16, 2022 at 16:07

# Desmos, 14 bytes

r=\ans_1\theta


Well...

Try it on Desmos!

• Hardcoding the input in a variable (in your program, it's the variable a) is not allowed. A program that would better conform to the I/O standards set by the community would be r=\ans_1\theta, where the input number is placed in the second expression box. Try It On Desmos! May 13, 2022 at 19:49
• @AidenChow Forgot about \ans_0. Thanks May 13, 2022 at 19:53
• Btw, you forgot edit this answer into the Desmos answers list here. May 14, 2022 at 2:49

# GFA-Basic 3.51 (Atari ST), 68 bytes

A manually edited listing in .LST format. All lines end with CR, including the last one.

PRO d(a)
F t=0TO 251
PL 160+t*COS(t/20)*a,100-t*SIN(t/20)*a
N t
RET


which expands to:

PROCEDURE d(a)
FOR t=0 TO 251
PLOT 160+t*COS(t/20)*a,100-t*SIN(t/20)*a
NEXT t
RETURN


NB: We use $$\251\$$ as the upper bound so that the curve stops on the x-axis rather than at some random position (because $$\251/20\approx 4\pi\$$).

# Wolfram Language (Mathematica), 22 bytes

PolarPlot[y#,{y,0,7}]&


Try it online!

I picked 7 for the plot range because it's a one-digit number that is close to $$\2\pi\$$ (so we get just around 1 rotation, slightly more).

Example result for input = 1:

Example when we replace 7 with 50 (makes it more accurate to the image in the original post, but is one byte longer):

# J, 28 bytes

plot@(**r.@o.@])(%~8*i.)@1e5


Try it online!

a=1

a=2

# R, 49 bytes

function(a)plot(cos(t<-0:9e3/1e3)*t*a,sin(t)*t*a)


Try it on rdrr.io!

• I think a is supposed to be taken as input. May 13, 2022 at 18:55
• @Giuseppe thanks, I somehow didn't notice this. May 13, 2022 at 19:06
• @pajonk - I think you can get away with only 99 points per quadrant to save a byte... but using complex numbers gives even bigger savings... May 17, 2022 at 8:08
• @DominicvanEssen hmm, I think I'll stick to the larger value, so it looks more like a line. The imaginary numbers idea - brilliant! May 17, 2022 at 8:17

# BQN, 50 bytesSBCS

(•math.Sin•Plot○(⊢×↕∘≠)•math.Cos)-2×π×999⥊99÷˜↕100


Run online!

The JS version of BQN has a plotting builtin, which I used for the same rosetta code task. This is just a golf of that.

# MATL, 13 bytes

9W:9/tJ*Ze*XG


Try it at MATL online!

### Explanation

9W    % Push 9. 2 raised to that. Gives 512
:     % Range. Gives [1 2 ... 512]
9/    % Divide each entry by 9
t     % Duplicate
J*    % Multiply each entry by imaginary unit
Ze    % Exponential of each entry
*     % Multiply each pair of entries
XG    % Plot


# Excel & VBA, 144 bytes

Cell B1 = SEQUENCE(90)/9*PI()
Cell C1 = B1#*COS(B1#)*A1
Cell D1 = B1#*SIN(B1#)*A1
VBA Immediate Window Set x=activesheet.Shapes.AddChart2(,73,,,,360):x.Chart.SetSourceData Source:=Range("C1:D96")


Could cut the ,,,,360 if the plot doesn't have to be square.

• You can get this down to somewhere around 109 bytes if you change cell B1's formula to =ROW(1:90)/9*PI() and the immediate window function to Sheet1.Shapes.AddChart2(,73,,,,360).Chart.SetSourceData[C1:D90] May 14, 2022 at 3:11

# SageMath, 69 68 bytes

lambda a,t=var('t'):parametric_plot((a*t*cos(t),a*t*sin(t)),(t,0,9))


Try it online!

Saved a byte thanks to Seggan!!!

### Original graph using 42 instead of 9

• You can replace the 42 with a 7, 8, or 9 to save 1 byte, although the graph wont be as big May 13, 2022 at 16:09
• @Seggan But it looks so cool! :D May 13, 2022 at 16:10
• @Seggan But a golf is a golf - thanks! :D May 13, 2022 at 16:17

## SVG(HTML5) + JavaScript (ES6), 77 76 + 96 = 172 bytes

f=a=>s.setAttribute("points",[...Array(9e3)].map((_,i)=>[Math.sin(i/=100)*i*a,Math.cos(i)*i*a]))
;f(.1)
<input value=.1 oninput=f(+value)><br>
<svg viewBox=-4,-4,8,8><polyline id=s fill=none stroke=red stroke-width=.05>

Edit: Saved 1 byte thanks to @Kaiido.

• You can omit the leading 0 in stroke-width. And I didn't check if it's part of your count but you can also remove this. in f(this.value) May 15, 2022 at 12:22
• @Kaiido There's a story behind that 0 - I was fiddling around trying to get something to work, but my problem was that I had a /, so nothing was working. Later I figured that I could remove the /, but forgot to remove the 0. Thanks for reminding me.
– Neil
May 15, 2022 at 13:41

# R, 42 bytes*

function(a,x=0:6e3/1e3)plot(a*x*pi*1i^x/2)


Try it at rdrr.io

Calculates the the points of the spiral as the real and imaginary parts of complex numbers, which is conveniently displayed directly as points on the complex plane by the R plot function.

*The *pi.../2 bit here is to scale the image so that the angle is in radians and achieve a distance between arms of exactly 2*pi. If we use an alternative unit of angular measurement, such as quadrants, we could drop this for 37 bytes: function(a,x=0:6e3/1e3)plot(a*x*1i^x).

Note also that the choice of 1e3 plotted points per quadrant was chosen to allow direct competition with pajonk's R answer; however, 99 plotted points per quadrant also gives a satisfactory output (the points overlap) and saves another byte: function(a,x=0:999/99)plot(a*x*1i^x).

# R + pracma library, 39 bytes

function(a)pracma::polar(r<-0:99/9,a*r)


Try it at rdrr.io

Using a dedicated polar function doesn't save much, if anything at all.

## Applesoft BASIC, 73 bytes

0GR
1COLOR=7
2INPUTR
3I=0
4PLOTCOS(I)*I*R+20,SIN(I)*I*R+20
5I=I+.1
6GOTO4


Clojure, 344 bytes

(defn s[a](doto(JFrame."")(.setPreferredSize(Dimension. 500 500))(.add(doto(proxy[JPanel][](paintComponent[g](.drawPolyline g (into-array Integer/TYPE(map #(+ 250(* a(/ % 20)(Math/cos(Math/toRadians %))))(range 3600)))(into-array Integer/TYPE(map #(- 250(* a(/ % 20)(Math/sin(Math/toRadians %))))(range 3600)))3600))))).pack(.setVisible true)))


Output for (s 1):