问题描述
我正在使用ARKit
我有相机x,y,z(笛卡尔坐标)和3D对象x,y,z。我试图在2D(x,y)中指向一个箭头(UIImageView),以显示相机应移动的位置,以便用户看到3D对象。
我尝试使用下面的代码使用反正切函数(矢量的方向)来计算箭头的方向,但是我怀疑坐标系有问题
func redirectArrow(bee: SCNNode,arrow: UIImageView) {
let (direction,position) = self.getUserVector()
let dx = bee.position.x - position.x
let dy = bee.position.y - position.y
let arctangent = atan(dy/dx)
arrow.transform = CGAffineTransform(rotationAngle: CGFloat(arctangent))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.redirectArrow(bee: bee,arrow: arrow)
}
}
getUserVector()的代码
func getUserVector() -> (SCNVector3,SCNVector3) { // (direction,position)
if let frame = self.sceneView.session.currentFrame {
let mat = SCNMatrix4(frame.camera.transform) // 4x4 transform matrix describing camera in world space
let dir = SCNVector3(-1 * mat.m31,-1 * mat.m32,-1 * mat.m33) // orientation of camera in world space
let pos = SCNVector3(mat.m41,mat.m42,mat.m43) // location of camera in world space
return (dir,pos)
}
return (SCNVector3(0,-1),SCNVector3(0,-0.2))
}
更新
感谢mnuages回答,现在使用以下代码将箭头指向3D对象
func redirectArrow(bee: SCNNode,position) = self.getUserVector()
let bee2DPosition = sceneView.projectPoint(bee.position)
let world2DPosition = sceneView.projectPoint(direction)
let dx = bee2DPosition.x - world2DPosition.x
let dy = bee2DPosition.y - world2DPosition.y
var arctangent: Float = atan(dy/dx)
if dx < 0 {
arctangent += Float(Double.pi)
}
arrow.transform = CGAffineTransform(rotationAngle: CGFloat(arctangent))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.redirectArrow(bee: bee,arrow: arrow)
}
}
解决方法
您需要projectPoint(_:)
API:
将点从场景的3D世界坐标系投影到渲染器的2D像素坐标系。