ARKit Calculate distance from a wall to the camera
ARKit Calculate distance from a wall to the camera
I’m developing a project with ARKit. I want to calculate the measure from a wall to the camera and it updates when I move away or I move closer.
Now, i have activated that it detects horizontal and vertical surfaces. When I get a surface, I calculate the distance from the camera position and the center of the surface. After I apply the calculus that it gets the distance between 2 points in a 3D space (Euclidean).
https://math.stackexchange.com/questions/42640/calculate-distance-in-3d-space
Is it correct? Can you help me?
class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {
let configuration = ARWorldTrackingConfiguration()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
configuration.planeDetection = [.horizontal, .vertical]
sceneView.session.run(configuration)
......
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
let plane = SCNPlane(width: CGFloat(planeAnchor.extent.x), height:
CGFloat(planeAnchor.extent.z))
let planeNode = SCNNode(geometry: plane)
planeNode.simdPosition = float3(planeAnchor.center.x, 0,
planeAnchor.center.z)
planeNode.eulerAngles.x = -.pi / 2
node.addChildNode(planeNode)
let distance = distanceFromCamera(x: planeAnchor.center.x, y: 0, z: planeAnchor.center.z)
let formatted = String(format: "Distance: %.2f", distance)
print(formatted) q
}
private func distanceFromCamera(x: Float, y:Float, z:Float) -> Float {
let cameraPosition = self.sceneView.session.currentFrame!.camera.transform.columns.3
print("Camera: (cameraPosition)")
let vector = SCNVector3Make(cameraPosition.x - x, cameraPosition.y - y, cameraPosition.z - z)
// Scene units map to meters in ARKit.
return sqrtf(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
}
}
1 Answer
1
Add Following method
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
guard let currentBall = self.currentBall else {return}
DispatchQueue.main.async {
if let centerPosition = self.hitTestCenterVector() {
let startPositionOfBall = currentBall.position
let distance = self.getDistanceBetween(vector1: centerPosition, vector2: startPositionOfBall)
self.lblDistance.text = String(format: "%.1f", distance) //meter
}
}
}
Just replace self.currentBall
in guard statement with your SCNNode
it is from where you want to cal. distance
self.currentBall
SCNNode
Now This is method to for calculations
func hitTestCenterVector () -> SCNVector3? {
let results = self.sceneView.hitTest(self.sceneView.center, types: .existingPlane)
if let firstObject = results.first {
return SCNVector3(firstObject.worldTransform.columns.3.x, firstObject.worldTransform.columns.3.y, firstObject.worldTransform.columns.3.z)
}
return nil
}
func getDistanceBetween(vector1:SCNVector3, vector2:SCNVector3) -> CGFloat {
return CGFloat(sqrt((vector1.x - vector2.x) * (vector1.x - vector2.x)
+ (vector1.y - vector2.y) * (vector1.y - vector2.y)
+ (vector1.z - vector2.z) * (vector1.z - vector2.z)))
}
Hope it is helpful
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Comments
Post a Comment