我想知道我的相机在 ARKit 中面向的方向,以便我在我前面的物体上进行的操作是正确的(说向左滑动向左移动)。
现在我尝试使用 POV 方向(不起作用,因为它始终是正的)和节点方向(photo.worldFront.z - 这将起作用,除非应用旋转,一旦旋转超过 180 度,方向是错误的)。
有什么建议?
你是对的,首先是pointOfView。
pointOfView
Hovewer 虽然rotation和eulerAngles都描述了摄像机面向的方向,但在使用物体(例如在相机的空间放置或移动物体)时使用它们并不简单。
rotation
eulerAngles
相反,在世界空间中设置您的位置或运动矢量,然后使用相机的transform将其转换为相机的空间。
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 中的相机高出半米。
myPosInCamSpace
z=-0.5
要将已经位于相机前方的物体向右移动 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添加到您前面的对象的位置。
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);
我通过使用位置管理器磁性标题找到了一个更简单的解决方案。
首先你需要这些功能。
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 度范围内的位置查看目的地,则会打印正确的查看!您可以根据需要自定义度数。
2 回答
你是对的,首先是
pointOfView
。Hovewer 虽然
rotation
和eulerAngles
都描述了摄像机面向的方向,但在使用物体(例如在相机的空间放置或移动物体)时使用它们并不简单。相反,在世界空间中设置您的位置或运动矢量,然后使用相机的
transform
将其转换为相机的空间。在 Obj-C 中它会是这样的:
将对象的位置设置为
myPosInCamSpace
。上面的示例将对象放在z=-0.5
的相机空间中,该空间比 AR 中的相机高出半米。要将已经位于相机前方的物体向右移动 5 厘米,请执行以下操作:
将
myVecInCamSpace
添加到您前面的对象的位置。第一修正案
如果你需要完全 360°(-π,π)的摄像机偏航用于记录或其他:
我通过使用位置管理器磁性标题找到了一个更简单的解决方案。
首先你需要这些功能。
创建一个位置管理器。
和
..
在你每秒或更新会话(_:ARSession,didUpdate:ARFrame)或使用计时器或你写的任何内容更新的函数内部之后:
“point2 将是你的位置”
因此,如果您想查找他是否在寻找您的位置,您必须进行此检查。
在此示例中,如果用户从 20 度范围内的位置查看目的地,则会打印正确的查看!您可以根据需要自定义度数。