# Script:Circular or spiral motion

Circular motion is achieved using the sin and cos functions:

``` x = cos(t)
y = sin(t)
```

where t is time (e.g. seconds). To control the radius r, origin (x0,y0 - the point to circle around), and speed (s - degrees per second), we have to add some more parameters:

``` x = x0 + r * cos(s * t)
y = y0 + r * sin(s * t)
```

sin and cos aren't builtin functions in HamsterSpeak, but there are scripts to calculate them in the 3rd Party HSI package. You only need the sine, cosine, sina, sinb, sinc, sind scripts and don't need any of the global variables or other things.

Because HamsterSpeak doesn't have floating point, the sine(angle,mult) script returns mult*sin(angle). The angle is measured in degrees (360 for a full circle).

For example, to move a slice in a circle of radius 100, making a revolution every 30 ticks, and circling the center of the screen:

```script, circling slice, begin
variable (sl, t, angle)
# The following causes positions to be measured from the centre of the screen
center slice (sl)

for (t, 0, 150) do (
angle := 360 * t / 30
put slice (sl, cosine(angle, 100), sine(angle, 100))
wait
)

free slice (sl)
end
```

To move in a spiral, you adjust the radius at the same time as the angle:

```script, spiralling slice, begin
variable (sl, t, angle, radius)
center slice (sl)

for (t, 0, 150) do (
angle := 360 * t / 30
radius := 100 -- t*100 / 150  # Spiral in from radius 100 to 0 in 150 ticks
put slice (sl, cosine(angle, radius), sine(angle, radius))
wait
)

free slice (sl)
end
```

However this will cause the movement speed to be proportional to the radius, moving fast at the beginning and slowing down to zero, as seen here: If we want to compensate for that to make the speed roughly uniform, it requires some significant changes, since angle is no longer proportional to t:

```define constant (9, spiral speed)  # Movement speed in pixels per tick

script, spiral, begin
variable (sl)
create rect(320, 200)  # Hide the map
center slice (sl)

variable (t, radius, angle, angular speed)
angle := 0
for (t, 0, 1000) do (
angular speed := 360 * spiral speed * 1000 / (1 + 3142 * 2 * radius) # Degrees per tick
if (angular speed > 60) then (angular speed := 60)
if (angular speed < 1) then (angular speed := 1)
angle += angular speed
#radius := 100 -- angle * 25 / 360  # Spiral in at 25 pixels per revolution
radius := 100 -- t*100 / 200      # Spiral in from radius 100 to 0 in 200 ticks
if (radius < 0) then (break)

put slice (sl, cosine(angle, radius), sine(angle, radius))
wait
)
end
```

There are two different "radius := ..." lines, which cause different spiral motions, uncomment the one you want:

The first produces an Archimedean spiral:

``` radius := 100 -- angle * 25 / 360  # Spiral in at 25 pixels per revolution
```

The second produces a logarithmic spiral:

``` radius := 100 -- t*100 / 200      # Spiral in from radius 100 to 0 in 200 ticks
```