Spirograph in Swift

Erica Sadun published a cool little Swift playground that draws images like the old Spirograph that we played with as kids. The thing is, it wasn’t immediately clear how to use it. I fooled around with it and got it working.

Here’s Erica’s part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import UIKit

struct SpirographGenerator : GeneratorType {

var pointOffset, dTheta, dR, minorRadius, majorRadius : Double
var theta = 0.0
typealias Element = CGPoint

init(majorRadius : Double, minorRadius : Double, pointOffset : Double, samples : Double)
{
self.pointOffset = pointOffset
self.dTheta = Double(M_PI) * (2.0) / samples
self.majorRadius = majorRadius
self.minorRadius = minorRadius
self.dR = majorRadius - minorRadius
}

mutating func next() -> CGPoint? {
var xT : Double = dR * cos(theta) + pointOffset * cos(dR * theta / minorRadius)
var yT : Double = dR * sin(theta) + pointOffset * sin (dR * theta / minorRadius)
theta = theta + dTheta
return CGPoint(x: CGFloat(xT), y: CGFloat(yT))
}
}

Now, how do you produce images from that? Basically, you just need to create an image context and draw into it. Here’s my part:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//  sample size
let n = 100

// offset in the image
let (majorRadius:Double, minorRadius:Double) = (48,-47)

// iterations
let iterations = 15


var spiro = SpirographGenerator(majorRadius: majorRadius, minorRadius: minorRadius, pointOffset: 13, samples: Double(n))

let dimension_2:CGFloat = 125

// image size
let size = CGSizeMake(dimension_2 * 2, dimension_2 * 2)

UIGraphicsBeginImageContext(size)
let ctx = UIGraphicsGetCurrentContext()
for i in 0…iterations*n {
let p:CGPoint? = spiro.next()
NSLog(“%@”,NSStringFromCGPoint(p!))
if i == 0 {
CGContextMoveToPoint(ctx, p!.x+dimension_2, p!.y+dimension_2)
}
else {
CGContextAddLineToPoint(ctx, p!.x+dimension_2, p!.y+dimension_2)
}

}
CGContextStrokePath(ctx)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

Now you should just be able to view the image by clicking on the eye icon. By varying the radii and the number of iterations, you can produce some neat images in an Xcode 6 Playground.

spirograph image

Edited on 2014-08-29 16-13-31 Generator is now GeneratorType and fixed issue with diappearing * symbols here and there.