二维箭头方向的 SCNVector3 到 SCNVector3

Posted

技术标签:

【中文标题】二维箭头方向的 SCNVector3 到 SCNVector3【英文标题】:SCNVector3 to SCNVector3 in 2D arrow direction 【发布时间】:2020-09-29 15:09:43 【问题描述】:

我正在使用 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)
    
    

【问题讨论】:

【参考方案1】:

projectPoint(_:) API 正是您所需要的:

将一个点从场景的 3D 世界坐标系投影到渲染器的 2D 像素坐标系。

【讨论】:

以上是关于二维箭头方向的 SCNVector3 到 SCNVector3的主要内容,如果未能解决你的问题,请参考以下文章

什么是三维向量什么是二维向量

matlab画矢量图?

通过向量扩展二维多边形

展开 SCNVector3/SCNVector4 值以打印?

创建指向指定位置方向的自定义指南针箭头

python怎样把箭头变为红色