SCNVector3 到 2D 箭头方向的 SCNVector3
SCNVector3 to SCNVector3 in 2D arrow direction
我正在使用 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, 0, -1), SCNVector3(0, 0, -0.2))
}
更新
感谢 mnuages 回答,箭头现在使用下面的代码指向 3D 对象
func redirectArrow(bee: SCNNode, arrow: UIImageView) {
let (direction, 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就是您所需要的:
Projects a point from the 3D world coordinate system of the scene to the 2D pixel coordinate system of the renderer.
我正在使用 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, 0, -1), SCNVector3(0, 0, -0.2))
}
更新
感谢 mnuages 回答,箭头现在使用下面的代码指向 3D 对象
func redirectArrow(bee: SCNNode, arrow: UIImageView) {
let (direction, 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就是您所需要的:
Projects a point from the 3D world coordinate system of the scene to the 2D pixel coordinate system of the renderer.