找到用户在ARKit中面向的方向

时间:2017-08-14 01:43:52

标签: swift scenekit arkit

我想知道我的相机在ARKit中面向的方向,因此我对前方物体的操作是正确的(向左滑动向左移动)。

现在我尝试过使用POV方向(不起作用,因为它总是正面)和节点方向(photo.worldFront.z - 这将起作用,除非应用旋转,一旦旋转超过180度方向错误)

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

你是第一次看pointOfView

Hovewer虽然rotationeulerAngles都描述了相机面向的方向,但当使用对象(例如放置或移动对象)时,使用它们并不简单em>你的前方,这是相机的空间。

相反,在世界空间中设置您的位置或运动矢量,然后使用相机的transform将其转换为相机的空间。

在Obj-C中它会是这样的:

simd_float4x4 transform = self.sceneView.pointOfView.simdTransform;
simd_float4 myPosInWorldSpace = simd_make_float4(0.0, 0.0, -0.5, 1);
simd_float4 myPosInCamSpace = simd_mul(transform, myPosInWorldSpace);

将对象的位置设置为myPosInCamSpace。上面的示例将对象放在z=-0.5的相机空间中,该空间比AR中的相机提前半米。

移动已经在相机前方的物体向右移动5厘米,如下所示:

simd_float4x4 transform = self.sceneView.pointOfView.simdTransform;
transform.columns[3].xyz=0; //drop cam translation
simd_float4 myVecInWorldSpace = simd_make_float4(0.05, 0.0, 0.0, 1);
simd_float4 myVecInCamSpace = simd_mul(transform, myVecInWorldSpace);

myVecInCamSpace添加到您前方对象的位置。

第一修正案

如果您需要完全360°(-π,π)的相机偏航进行测井或其他任何事情:

simd_float4x4 transform = self.sceneView.pointOfView.simdTransform;
simd_float3 cam_right = transform.columns[0].xyz; //for completeness
simd_float3 cam_up = transform.columns[1].xyz;  //for completeness
simd_float3 cam_ahead = transform.columns[2].xyz;
float yaw = atan2f(cam_ahead.x, cam_ahead.z);

答案 1 :(得分:0)

我使用位置管理器磁性标题找到了一个更简单的解决方案。

首先你需要these functions

func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
func getBearingBetweenTwoPoints1(point1 : CLLocation, point2 : CLLocation) -> Double {

    let lat1 = degreesToRadians(degrees: point1.coordinate.latitude)
    let lon1 = degreesToRadians(degrees: point1.coordinate.longitude)

    let lat2 = degreesToRadians(degrees: point2.coordinate.latitude)
    let lon2 = degreesToRadians(degrees: point2.coordinate.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(radians: radiansBearing)
}

创建位置管理器。

import CoreLocation

class YourClass: CLLocationManagerDelegate {

...

var locationManager:CLLocationManager = CLLocationManager()
locationManager.delegate = self

locationManager.startUpdatingHeading()
var degreesRange:Int = 20

在你每秒或会话更新的函数内部(_:ARSession,didUpdate:ARFrame)或者使用计时器或你写的任何内容:

" point2将是您的位置"

var degrees:Double = getBearingBetweenTwoPoints1(point1: locationManager.location!, point2: CLLocation(latitude: 70.500000, longitude: 85.555555))

if(degrees < 0 ) {
    degrees = 360 + degrees
}

var locationManagerHeadingMagnetic:Double = lm.heading!.magneticHeading

print("He Is Looking \(locationManagerHeadingMagnetic)")
print("He should Look: \(degrees)")

所以如果你想找到他是否在寻找你的位置,你必须做这个检查。

var difference:Double = locationManagerHeadingMagnetic - degrees
print("Difference \(difference)")

if(difference < degreesRange && difference > -degreesRange) {
    print("Correct Looking!")

} else {

    if(difference <= -degreesRange || difference > 180) {
        print("You have to look more right!")
    } else {
        print("You have to look more left")
    }
}

在此示例中,如果用户从20度范围内的位置查看目的地,则会打印正确的查看!您可以根据需要自定义度数。