A year of thinking in circles: 2015 (Xcode 6.1)


Theory

There's no way around it, next year is going to be all about thinking in terms of time. The Apple Watch and the accompanying WatchKit that is soon to be released to developers will bring with it new ways of visualising and portraying time. And although the watch itself isn't round, the circular aesthetic is tightly linked to our ideas of what a watch is. Hence the Apple Watch interface has its fair share of circles. These not only fulfil the requirement of watchness but also provide a sense of space around objects and icons that are close together.

As with every Apple product, it will likely be the case that this circular aesthetic will spread far and wide. Already circular visualisations of data are popular and I expect to see more and more of the things we see and do becoming circular. Given this, it is time to start thinking about working with circles.

The opportunities for scaling and rotating circles are vast. As we've seen from early demonstrations of the Apple Watch, circles can grow and shrink, shift and rotate. Once circles become part of an interactive interface, squares and rectangles start to appear rather limited and like they've been hogging all the space for far too long.

Was it in part the dream of 3D interfaces, which have been largely centred on rectangles, that delayed the age of the circle? Or the lack of serious space restrictions prior to the smartwatch? Whatever the reason, the flatness and scaling back and removal of features like Cover Flow have left the gate wide open for innovative 2D interfaces.

This doesn't discount future 3D innovations, but it does demonstrate that there's more to life than rectangles and that future UIs will be unlikely to ignore the importance of the circle.

Practice: Polygons

One of the first things to crack are regular polygons. A watch face, for example, relies on the positioning of numbers at regular intervals and it is by placing a polygon within a circle that we can make these divisions. In this example the 12, 3, 6 and 9 are pinpointed (note: all examples are written in JavaScript and HTML5, if you have JS switched off or are using an older browser you won't see anything): 

And here all 12 hour positions are identified by way of a twelve-sided polygon:

Shrinking the radius but keeping the same origin it is possible to inset designs, just as we are used to seeing on clock and watch faces. And once we have the necessary points these can be used to not only draw polygons but for overall positioning as you see in the clock example at the top of this post.

Code: In Swift

In Swift, circles are a trivial thing to achieve using UIBezierPath:
UIBezierPath(ovalInRect: CGRect(x: 100,y: 100,width: 100,height: 100))
Polygons are slightly trickier but given a bit of trigonometry (and a little assistance from here and here) it is possible to throw together some rough and ready code to make regular polygons with any number of sides happen:
func degree2radian(a:Double)->Double {return M_PI * a/180
}

func polygon(sides:Int,x:Double,y:Double,radius:Double)->[CGPoint] {
    var angle = degree2radian(360/Double(sides))
    var cx:Double = x // x origin
    var cy:Double = y // y origin
    var r:Double  = radius // radius of circle
    var i=0
    var points = [CGPoint]()
    while i <= sides {
        var xpo = cx + r * cos(angle * Double(i))
        var ypo = cy + r * sin(angle * Double(i))
        points.append(CGPoint(x: xpo, y: ypo))
        i++;
    }
    return points
}



var points = polygon(12,100,100,500)
var cpg = points[0]
var bpg = UIBezierPath()
bpg.moveToPoint(cpg)
for p in points {
    bpg.addLineToPoint(p)
}
bpg
These examples are written for a Playground where clicking on the plus icon in the preview will display the shapes. I'll move on to drawing in a UIView in a later post but to get a feel for how to distribute numbers around a clock face using polygons in Xcode here's an example that you can copy and paste into the viewDidLoad of your initial UIViewController:
// create function to covert degrees to radians, necessary for use of cos() and sin()
func degree2radian(a:Double)->Double {
            return M_PI * a/180
        }

// creates the points of the polygon    
func polygon(sides:Int,x:Double,y:Double,radius:Double)->[CGPoint] {
       let angle = degree2radian(360/Double(sides))
       let cx:Double = x // x origin
       let cy:Double = y // y origin
       let r:Double  = radius // radius of circle
       var i=0
       var points = [CGPoint]()
       while i <= sides {
            let xpo = cx + r * cos(angle * (Double(i)+(Double(sides)/4*3)))
            let ypo = cy + r * sin(angle * (Double(i)+(Double(sides)/4*3)))
            // add (Double(sides)/4*3) to multiplication to ensure that index twelve corresponds to the twelve position, it will also ensure that minutes and seconds are correctly distributed
            points.append(CGPoint(x: xpo, y: ypo))
            i++;
        }
        return points
    }
        
        
// get the array of points along the polygon        
var points = polygon(12,Double(CGRectGetMidX(self.view.frame)),Double(CGRectGetMidY(self.view.frame)),100)

// add a label at each point of the polygon
for p in enumerate(points) {
        if p.index >= 1 {
        // I don't want to include zero in the numbers
          let a = UILabel(frame: CGRect(origin: p.element, size: CGSize(width: 20, height: 20)))
          a.text = String(p.index)
          self.view.addSubview(a);
        }
     }
What you should see when you build and run is something like this:


And that's where I'll not only finish for now, but also where I'll start from in the next post.

Note: in this post I update the polygon code to work consistently using CGFloat for layout purposes on 32-bit devices.

Further reading (Design and UI-based)

'Beyond the Apple Watch: 4 Features Show Direction of UX' (HOW)

'Design Principles: Visual Perception And The Principles Of Gestalt' (Smashing Magazine)

'Why Rounded Corners are Easier on the Eyes' (uxmovement)

'Smartwatch UI Design: A Battle of Circles and Squares' (Sitepoint)

'How do rounded corners affect usability?' (ux.stackexchange.com)

'Humans Prefer Curved Visual Objects' (Moshe Bar and Maital Neta, Psychological Science [PDF])

Further reading (code-based)

'playing with ellipse in Swift part.1' (gracefullycoded.com)

'playing with ellipse in swift Part.2' (gracefullycoded.com)



Endorse on Coderwall

Comments