Advertisement
  1. Code
  2. OS X

How To Create Vector Graphics on iOS

by
Read Time:17 minsLanguages:

Introduction

Graphical resources in the digital world are of two basic types, raster and vector. Raster images are essentially a rectangular array of pixel intensities. Vector graphics, on the other hand, are mathematical representations of shapes.

While there are situations in which raster images are irreplaceable (photos, for example), in other scenarios, vector graphics make capable substitutes. Vector graphics make the task of creating graphical resources for multiple screen resolutions trivial. At the time of writing, there are at least half a dozen screen resolutions to contend with on the iOS platform.

One of the best things about vector graphics is that they can be rendered to any resolution while remaining absolutely crisp and smooth. This is why PostScript and TrueType fonts look sharp at any magnification. Because smartphone and computer displays are raster in nature, ultimately, the vector image does need to be rendered to the display as a raster image at the appropriate resolution. This is usually taken care of by the low-level graphics library and the programmer doesn’t need to worry about this.

1. When to Use Vector Graphics?

Let’s take a look at some scenarios where you should consider using vector graphics.

App and Menu Icons, User Interface Elements

A few years ago, Apple eschewed skeuomorphism in the user interface of its apps and iOS itself, in favour of bold and geometrically precise designs. Take a look at the Camera or Photo app icons, for example.

More likely than not, they were designed using vector graphics tools. Developers had to follow suit and most of the popular (non-game) apps underwent a complete metamorphosis in order to conform to this design paradigm.

Games

Games with simple graphics (think Asteroids) or geometric themes (Super Hexagon and Geometry Jump come to mind) can have their sprites rendered from vectors. The same applies to games that have procedurally generated levels.

Images

Images in which you want to inject a small amount of randomness to get multiple versions of the same basic shape.

2. Bezier Curves

What are Bezier curves? Without delving into the mathematical theory, let’s just talk about the features that are of practical use to developers.

Degrees of Freedom

Bezier curves are characterized by how many degrees of freedom they have. The higher this degree, the more variation the curve can incorporate (but also the more mathematically complex it is).

Degree one Beziers are straight line segments. Degree two curves are called quad curves. Degree three curves (cubics) are the ones we’ll focus on, because they offer a good compromise between flexibility and complexity.

Cubic Beziers can represent not only simple smooth curves, but also loops and cusps. Several cubic Bezier segments can be hooked up end to end to form more complicated shapes.

Cubic Beziers

A cubic Bezier is defined by its two end points and two additional control points that determine its shape. In general, a degree n Bezier has (n-1) control points, not counting the end points.

An attractive feature of cubic Beziers is that these points have a significant visual intepretation. The line connecting an end point to its adjacent control point acts as a tangent to the curve at the end point. This fact is useful for designing shapes. We’ll exploit this property later in the tutorial.

Geometric Transforms

Because of the mathematical nature of these curves, you can easily apply geometric transforms to them, such as scaling, rotation, and translation, without any loss of fidelity.

The following image shows a sampling of different kinds of shapes that a single cubic Bezier can take. Notice how the green line segments act as tangents to the curve.

Cubic Bezier ShapesCubic Bezier ShapesCubic Bezier Shapes

3. Core Graphics and the UIBezierPath Class

On iOS and OS X, vector graphics are implemented using the C-based Core Graphics library. Built on top of this is UIKit/Cocoa, which adds a veneer of object orientation. The workhorse is the UIBezierPath class (NSBezierPath on OS X), an implementation of a mathematical Bezier curve.

The UIBezierPath class supports Bezier curves of degree one (straight line segments), two (quad curves), and three (cubic curves).

Programmatically, a UIBezierPath object can be built piece-by-piece by appending new components (subpaths) to it. To facilitate this, the UIBezierPath object keeps track of the currentPoint property. Every time you append a new path segment, the last point of the appended segment becomes the current point. Any additional drawing you do generally starts at this point. You can explicitly move this point to a desired location.

The class has convenience methods for making commonly used shapes, such as arcs and circles, (rounded) rectangles, etc. Internally, these shapes have been built by connecting several subpaths.

The overall path can be either an open or closed shape. It can even be self-intersecting or have multiple closed components.

4. Getting started

This tutorial is meant to serve as a beyond-the-basics look at vector graphics generation. But even if you are an experienced developer who hasn’t used Core Graphics or UIBezierPath before, you should be able to follow along. If you’re new to this, I recommend skimming through the UIBezierPath class reference (and the underlying Core Graphics functions) if you’re not already familiar with it. We can only exercise a limited number of features of the API in a single tutorial.

Enough talk. Let’s start coding. In the remainder of this tutorial, I will present two scenarios where vector graphics are the ideal tool to use.

Fire up Xcode, create a new playground, and set the platform to iOS. Incidently, Xcode playgrounds are another reason why working with vector graphics is now fun. You can tweak your code and get instant visual feedback. Note that you should be using the latest stable version of Xcode, which is 7.2 at the time of this writing.

Scenario 1: Making Cloud Shapes

We’d like to generate images of clouds that adhere to a basic cloud shape while having some randomness so that each cloud looks different. The basic design I’ve settled on is a compound shape, defined by several circles of random radii centered along an elliptical path of random size (within appropriate ranges).

To clarify, here’s what the overall object looks like if we stroked the vector path instead of filling it.

Anatomy of a CloudAnatomy of a CloudAnatomy of a Cloud

If your geometry is a bit rusty, then this Wikipedia image shows what an ellipse looks like.

EllipseEllipseEllipse

Some Utility Functions

Let’s start by writing a couple of helper functions.

The random(lower:upper:) function uses the built-in arc4random_uniform() function to generate random numbers in the range lower and (upper-1). The circle(at:center:) function generates a Bezier path, representing a circle with a given center and radius.

Generating Points and Paths

Let’s now focus on generating the points along the elliptical path. An ellipse centered at the origin of the coordinate system with its axes aligned along the coordinate axes has a particularly simple mathematical form that looks like this.

We assign random values for the lengths of its major and minor axis so that the shape looks like a cloud, more elongated horizontally than vertically.

We use the stride() function to generate regularly spaced angles around the circle, and then use map() to generate regularly spaced points on the ellipse using the above mathematical expression.

We generate the central “mass” of the cloud by joining the points along the elliptical path. If we don’t, we’ll get a big void at the center.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.