我正在做一个项目,我需要在增强现实中的真实世界位置上放一个箭头。 (箭头只是一个倒置圆锥体上的圆柱体-我说这是为了解释placeArrow()中场景文件中的内容。)
该想法是获取当前位置,找出预定义第二位置的方向和距离,然后将箭头放在增强现实中的该位置上。
我感觉自己快要到了,但是每次发射时,箭头几乎都在我的右手90度而不是实际位置的方向出现。
有人做过类似的事情吗?我在做什么错了?
注意:可以在这里找到MatrixHelper:https://github.com/inorganik/MatrixHelper/blob/master/MatrixHelper.swift
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) -> SCNNode? {
// Place arrow does all this.
return placeArrow()
}
func setAnchor() {
let destination = CLLocationCoordinate2D(latitude: <latitude>, longitude: <longitude>)
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() -> 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) -> 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) -> Double {
func degreesToRadians(_ degrees: Double) -> Double { return degrees * Double.pi / 180.0 }
func radiansToDegrees(_ radians: Double) -> 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)
}
}