# Swift Tip: Vector Algebra with Protocols

In last week's Swift Talk we discussed the vector algebra required to build a routing graph for our running trail app. To work out where the tracks overlap, we needed to calculate the closest distance from a point to a line segment.

We won't repeat the math here, but we'll highlight a detail of the implementation.

For testing purposes we wanted to calculate with `CGPoint`s, which makes it easy to draw the points in a view. In the final app we want to calculate with Core Location coordinates. It's important to note that geographic coordinates are coordinates on a sphere, but for our use case, we'll pretend that the earth is flat — it's a good enough approximation for the small region we're doing our routing in.

Instead of implementing the vector operations first on `CGPoint`, and then re-writing them on `CLLocationCoordinate2D`, we decided to introduce a simple protocol:

```								```protocol Vector2 {
associatedtype Component: Numeric
var x: Component { get }
var y: Component { get }
init(x: Component, y: Component)
}
```
```

This protocol represents a vector with two numeric components, `x` and `y`. We're using an associated type to specify the type of the components: in our case they can be of type `CGFLoat` (for `CGPoint`) or `CLLocationDegrees` (for `CLLocationCoordinate2D`). Since `CGPoint` already has all the protocol requirements, conforming it to `Vector2` is a one-liner:

```								```extension CGPoint: Vector2 {}
```
```

Now we can start to define vector operations on the `Vector2` protocol, for example the dot product and vector addition:

```								```extension Vector2 {
func dot(_ other: Self) -> Component {
return x * other.x + y * other.y
}

static func +(l: Self, r: Self) -> Self {
return Self(x: l.x + r.x, y: l.y + r.y)
}
}
```
```

Since the operations are defined on the protocol, we get all of them for free when we conform a new type to the protocol; for instance, with `CLLocationCoordinate2D`:

```								```extension CLLocationCoordinate2D: Vector2 {
var x: CLLocationDegrees { return longitude }
var y: CLLocationDegrees { return latitude }
init(x: CLLocationDegrees, y: CLLocationDegrees) {
self.init(latitude: y, longitude: x)
}
}
```
```

If you'd like to learn more, the first episode in this Collection is public. To follow our progress, you can Subscribe. 🤓

Map Routing

### Shortest Distance from Point to Line

We start implementing the routing logic by looking at the problem of calculating the shortest distance from a point to a line.

Episode 128 · November 23, 2018

### Map Routing

7 Episodes · 2h 54m

## Recent Posts

• ### Book Update: Thinking in SwiftUI

Updated for iOS 17 – final release

• ### Book Update: Thinking in SwiftUI

Updated for iOS 17 – beta

• ### Thinking in SwiftUI: Live Q&A

A Q&A For Our Book Release

• ### Transitions in SwiftUI

Simple but powerful

• ### Aspect Ratios in SwiftUI

A Look Below the Hood