AR测量

作者: KeepFighting | 来源:发表于2017-07-26 17:32 被阅读82次
    • 启动ARSession
     override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            
            // Create a session configuration
            let configuration = ARWorldTrackingSessionConfiguration()
              configuration.planeDetection = .horizontal
            // Run the view's session
            sceneView.session.run(configuration)
        }
        
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            
            // Pause the view's session
            sceneView.session.pause()
        }
    
    • 提示检测状态
     sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin,ARSCNDebugOptions.showFeaturePoints]
    
      sceneView.showsStatistics = true
    
       func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
            
            switch camera.trackingState {
            case .normal:
    //            tipLabel.text = "Tracking State Normal!"
                 tipLabel.text = "跟踪状态正常!"
                
                tipLabel.textColor = .green
            case .notAvailable:
    //            tipLabel.text = "Tracking State notAvailable!"
                tipLabel.text = "跟踪状态无效!"
    
                tipLabel.textColor = .red
            case .limited(let reason):
                switch reason {
                case .excessiveMotion:
    //                tipLabel.text = "Tracking limited: excessiveMotion!"
                    tipLabel.text = "摄像头过度运动!"
    
                case .initializing:
    //                tipLabel.text = "Tracking limited: initializing!"
                    tipLabel.text = "正在初始化!"
    
                case .insufficientFeatures:
    //                tipLabel.text = "Tracking limited: insufficientFeatures!"
                    tipLabel.text = "特征点不够多!"
    
                case .none:
    //                 tipLabel.text = "Tracking limited!"
                     tipLabel.text = "检测异常"
    
                }
              tipLabel.textColor = .yellow
    
            }
        }
    
    • 屏幕坐标转换成世界坐标
    //from apple
    extension ViewController {
        func worldPositionFromScreenPosition(_ position: CGPoint,
                                             objectPos: SCNVector3?,
                                             infinitePlane: Bool = false) -> (position: SCNVector3?, planeAnchor: ARPlaneAnchor?, hitAPlane: Bool) {
            
            // -------------------------------------------------------------------------------
            // 1. Always do a hit test against exisiting plane anchors first.
            //    (If any such anchors exist & only within their extents.)
            
            let planeHitTestResults = sceneView.hitTest(position, types: .existingPlaneUsingExtent)
            if let result = planeHitTestResults.first {
                
                let planeHitTestPosition = SCNVector3.positionFromTransform(result.worldTransform)
                let planeAnchor = result.anchor
                
                // Return immediately - this is the best possible outcome.
                return (planeHitTestPosition, planeAnchor as? ARPlaneAnchor, true)
            }
            
            // -------------------------------------------------------------------------------
            // 2. Collect more information about the environment by hit testing against
            //    the feature point cloud, but do not return the result yet.
            
            var featureHitTestPosition: SCNVector3?
            var highQualityFeatureHitTestResult = false
            
            let highQualityfeatureHitTestResults = sceneView.hitTestWithFeatures(position, coneOpeningAngleInDegrees: 18, minDistance: 0.0, maxDistance: 0.05)
            
            if !highQualityfeatureHitTestResults.isEmpty {
                let result = highQualityfeatureHitTestResults[0]
                featureHitTestPosition = result.position
                highQualityFeatureHitTestResult = true
            }
            
            // -------------------------------------------------------------------------------
            // 3. If desired or necessary (no good feature hit test result): Hit test
            //    against an infinite, horizontal plane (ignoring the real world).
            
            if infinitePlane || !highQualityFeatureHitTestResult {
                
                let pointOnPlane = objectPos ?? SCNVector3Zero
                
                let pointOnInfinitePlane = sceneView.hitTestWithInfiniteHorizontalPlane(position, pointOnPlane)
                if pointOnInfinitePlane != nil {
                    return (pointOnInfinitePlane, nil, true)
                }
            }
            
            // -------------------------------------------------------------------------------
            // 4. If available, return the result of the hit test against high quality
            //    features if the hit tests against infinite planes were skipped or no
            //    infinite plane was hit.
            
            if highQualityFeatureHitTestResult {
                return (featureHitTestPosition, nil, false)
            }
            
            // -------------------------------------------------------------------------------
            // 5. As a last resort, perform a second, unfiltered hit test against features.
            //    If there are no features in the scene, the result returned here will be nil.
            
            let unfilteredFeatureHitTestResults = sceneView.hitTestWithFeatures(position)
            if !unfilteredFeatureHitTestResults.isEmpty {
                let result = unfilteredFeatureHitTestResults[0]
                return (result.position, nil, false)
            }
            
            return (nil, nil, false)
        }
    }
    
    • 算出2个世界坐标的差值
       // 计算2个点的距离
       func distance(startNode: SCNNode, endNode: SCNNode) -> Float {
           let vector = SCNVector3Make(startNode.position.x - endNode.position.x, startNode.position.y - endNode.position.y, startNode.position.z - endNode.position.z)
           // Scene units map to meters in ARKit.
           return sqrtf(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
       }
       ```
    
    - 连线
    
    

    相关文章

      网友评论

          本文标题:AR测量

          本文链接:https://www.haomeiwen.com/subject/socokxtx.html