# Drawing Arc on a map using multiple points: getting proper direction and intermediate point coordinates

I am using the following Swift code to create arcs using Apple's MKMap framework. This should give an idea how things are being calculated...

``````import Foundation
import UIKit
import MapKit

class IGAArcRenderer: MKOverlayPathRenderer {
var polyline: MKPolyline
var arcCentreMapPoint: MKMapPoint
var initialBearing : Double
var finalBearing : Double

init(polylineIn: MKPolyline,centreCoordinates: CLLocationCoordinate2D,initBearing: Double,finalBearing: Double) {
polyline = polylineIn
self.arcCentreMapPoint = MKMapPoint(centreCoordinates)
self.initialBearing = initBearing
self.finalBearing = finalBearing
super.init(overlay: polyline)
setup()
}

override func createPath() {
let points = polyline.points()
let startPoint = point(for: points[0])
let endPoint = point(for: points[1])

// Defining our new curved path using Bezier path
let myPath = UIBezierPath()
myPath.move(to: startPoint)

let arcCentre = point(for: arcCentreMapPoint)

// Radius to Start and End Points
let radiusStart = CGPointDistance(from: arcCentre, to: startPoint)
let radiusEnd = CGPointDistance(from: arcCentre, to: endPoint)

// Calculate which direction the arc should go when is drawn.
// If the following value is greater than 0, go clockwise
//let c = (startPoint.x-arcCentre.x)*(endPoint.y-arcCentre.y)-(startPoint.y-arcCentre.y)*(endPoint.x-arcCentre.x)
//let direction = c<0 ? false : true

/* NOTE: This code is working and draws an arc, which is not always perfect due to differences in radius
startAngle: startAngle,
endAngle: endAngle,
clockwise: direction)
*/

// Draw an arc by adding a number of lines determined by delta radius and delta angle
let numpoints = 100
var stepAngle : CGFloat = 0.0

if startAngle>=0 && endAngle>=0 {
stepAngle = (endAngle-startAngle)/CGFloat(numpoints)
}
else if startAngle<0 && endAngle>=0 {
stepAngle = (endAngle+startAngle)/CGFloat(numpoints)
}
else if startAngle>=0 && endAngle<0 {
stepAngle = (endAngle+startAngle)/CGFloat(numpoints)
}
else if startAngle<0 && endAngle<0 {
stepAngle = (endAngle-startAngle)/CGFloat(numpoints)
}

print("........ C \(c)")
print("........ START ANGLE \(startAngle)")
print("........ END ANGLE \(endAngle)")
print("........ STEP ANGLE 11 \(endAngle-startAngle)")
print("........ STEP ANGLE 22 \(stepAngle)")

// For each point, calculate the CGPoint based on the radius and angle
// and draw a line to this point
for i in 0..<numpoints {

var angleCurrent : CGFloat = 0.0

// Trying to play here to get the right direction
if startAngle>=0 && startAngle>endAngle {
angleCurrent = startAngle+CGFloat(i)*stepAngle // ORIGINAL
}
else if startAngle<0 && startAngle>endAngle {
angleCurrent = startAngle-CGFloat(i)*stepAngle // ORIGINAL
}
if startAngle>=0 && startAngle<endAngle {
angleCurrent = startAngle-CGFloat(i)*stepAngle // ORIGINAL
}
else {
angleCurrent = startAngle+CGFloat(i)*stepAngle // ORIGINAL
}

// Find the CGPoint
let newLocation = CGPoint(x: pi_x, y: pi_y)

}

path = myPath.cgPath
}

func CGPointDistanceSquared(from: CGPoint, to: CGPoint) -> CGFloat {
return (from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y)
}

func CGPointDistance(from: CGPoint, to: CGPoint) -> CGFloat {
return sqrt(CGPointDistanceSquared(from: from, to: to))
}

func deg2rad(Deg deg: CGFloat) -> CGFloat {
return (deg * .pi / 180.0);
}

return (rad * 180 / .pi);
}
}
``````

Sometimes, the arcs are drawn perfectly, sometimes there are problems with finding the right direction and calculation of angle step value. Here are some examples of what I got with the key values. For the first image, there is a problem with calculating the proper angle step for the first arc (should be around 0.017), but the second arc is drawn perfectly. For the third image, the arc is going the wrong direction, whereas in all other cases, the direction is good.

Case 1
START POINT (latitude: 25.41505833, longitude: 85.23135556)
CENTER POINT (latitude: 25.49688333, longitude: 84.91539167)
END POINT (latitude: 25.59042, longitude: 85.08992)

Case 3
START POINT (latitude: 25.37544722, longitude: 85.0547)
CENTER POINT (latitude: 25.62390278, longitude: 85.28933611)
END POINT (latitude: 25.59042, longitude: 85.08992)

Is there anyone here with good knowledge of geometry?