title: Placing a object in AR based on GPS coordinates iOS
body: <p>I am working on a project where I need to place an arrow over a real world position in Augmented Reality. (The arrow is simply a cylinder over an upside down cone - I say this to explain what is in the scene file in placeArrow().)</p>
  
  <p>The idea is to take the current position, figure out the direction and distance of a predefined second position, and place the arrow over that position in augmented reality.</p>
  
  <p>I feel like I am almost there, but whenever I fire it up, the arrow almost appears 90 degrees to my right instead of in the direction of the actual location.</p>
  
  <p>Has anyone done anything similar to this? What am I doing wrong?</p>
  
  <p>Note: MatrixHelper can be found here: <a href="https://github.com/inorganik/MatrixHelper/blob/master/MatrixHelper.swift" rel="nofollow noreferrer">https://github.com/inorganik/MatrixHelper/blob/master/MatrixHelper.swift</a></p>
  
  <pre><code>import UIKit
  import ARKit
  import MapKit
  
  class ViewController: UIViewController, ARSCNViewDelegate, CLLocationManagerDelegate {
  
      // All the IBOutlets
      @IBOutlet weak var sceneView: ARSCNView!
  
      // Private variables
      let locationManager = CLLocationManager()
      var location : CLLocation?
  
      override func viewDidLoad() {
  
          // Setup the view, the AR, and the location manager.
          super.viewDidLoad()
          setupAr()
          setupLocationManager()
  
      }
  
      override func didReceiveMemoryWarning() {
          super.didReceiveMemoryWarning()
      }
  
      func setupAr() {
  
          // Set up all the Augmented reality stuff.
          let configuration = ARWorldTrackingConfiguration()
          sceneView.session.run(configuration)
          sceneView.delegate = self
  
      }
  
      func setupLocationManager() {
  
          // Set up all the Location Manager stuff.
          locationManager.delegate = self
          locationManager.desiredAccuracy = kCLLocationAccuracyBest
          locationManager.requestAlwaysAuthorization()
          locationManager.startUpdatingLocation()
  
      }
  
      func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
  
          // If we haven't already set up everything, set it up.
          if location == nil {
              setAnchor()
          }
  
      }
  
      func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -&gt; SCNNode? {
  
          // Place arrow does all this.
          return placeArrow()
  
      }
  
      func setAnchor() {
  
          let destination = CLLocationCoordinate2D(latitude: &lt;latitude&gt;, longitude: &lt;longitude&gt;)
          let destinationLocation = CLLocation(latitude: destination.latitude, longitude: destination.longitude)
  
          // Get the current location and its distance and bearing.
          location = locationManager.location
          let distance = location!.distance(from: destinationLocation)
          let bearing = location!.coordinate.bearing(to: destination)
  
          // Start from scratch, move the appropriate distance, and rotate appropriately.
          var resetToHorizon = MatrixHelper.resetToHorizon(matrix_identity_float4x4)
          resetToHorizon.columns.3.z = -distance
          let transform = MatrixHelper.rotateMatrixAroundY(degrees: Float(bearing), matrix: resetToHorizon)
  
          // Add the anchor.
          let anchor = ARAnchor(transform: transform)
          sceneView.session.add(anchor: anchor)
  
      }
  
      func placeArrow() -&gt; SCNNode {
  
          // Create the cylinder and cone and add them.
          let cylinderNode = createSceneItem(art: "art.scnassets/Arrow.scn", item: "cylinder", position: SCNVector3(0, 3, 0))
          let coneNode = createSceneItem(art: "art.scnassets/Arrow.scn", item: "cone", position: SCNVector3(0, -1, 0))
          cylinderNode.addChildNode(coneNode)
  
          // Return it.
          return cylinderNode
  
      }
  
      func createSceneItem(art: String, item: String, position: SCNVector3) -&gt; SCNNode{
  
          // Create the scene, add the node, give it a name.
          let scene = SCNScene(named: art)
          let node = scene?.rootNode.childNode(withName: item, recursively: false)
          node?.name = item
  
          // Position it and return it.
          node?.position = position
          return node!
  
      }
  }
  
  extension CLLocationCoordinate2D {
      func bearing(to point: CLLocationCoordinate2D) -&gt; Double {
          func degreesToRadians(_ degrees: Double) -&gt; Double { return degrees * Double.pi / 180.0 }
          func radiansToDegrees(_ radians: Double) -&gt; Double { return radians * 180.0 / Double.pi }
  
          let lat1 = degreesToRadians(latitude)
          let lon1 = degreesToRadians(longitude)
  
          let lat2 = degreesToRadians(point.latitude);
          let lon2 = degreesToRadians(point.longitude);
  
          let dLon = lon2 - lon1;
  
          let y = sin(dLon) * cos(lat2);
          let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
          let radiansBearing = atan2(y, x);
  
          return radiansToDegrees(radiansBearing)
      }
  }
  </code></pre>