Swift SCNNode 3D立方体旋转到立方体上的一个点

时间:2017-07-21 19:31:00

标签: ios swift scenekit

问题:尝试将立方体旋转到立方体本身的某个点。该点是随机创建的,它应该出现在屏幕的中心。

尝试使用lookAtConstraint并在func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)中分配了随机点。但没有奏效(评论)

 cube = SCNNode(geometry: sphereGeometry)
        cube.position = SCNVector3Make(0.0, 0.0, 0.0)
        gamescn.rootNode.addChildNode(cube)

        cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 40)
        gamescn.rootNode.addChildNode(cameraNode)

        lookAtConstraint

//        lookAtConstraint = SCNLookAtConstraint(target: cube)
//        lookAtConstraint.isGimbalLockEnabled = true
//        cameraNode.constraints = [lookAtConstraint]

还试图获得偏差第一个中心点(初始[0,0,距离中心的距离]) - 然后cube.eulerAngles = deviation中的func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)。但是立方体随机旋转。

1 个答案:

答案 0 :(得分:0)

我提出了一个简单的3D几何解决方案。那里可能还有其他优雅的解决方案。 以下是我实现的目标 -

制作了两个实用功能来获得asin& acos组成两点之间的角度 -

func angleBetweenVectorsCos(_ vectorB:SCNVector3) -> SCNFloat {
        let cosineAngle = (dot(vector: vectorB) / (magnitude * vectorB.magnitude))
        return SCNFloat(acos(cosineAngle))
}

func angleBetweenVectorsSin(_ vectorB:SCNVector3) -> SCNFloat {
        let cosineAngle = angleBetweenVectorsCos(vectorB)
        let sinangle = sqrt(1-cosineAngle*cosineAngle)
        return SCNFloat(acos(sinangle))
 }

然后 - 在func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)函数中我指定角度计算

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
        if time > rotationTimer{


            let angleCos = lastposition.angleBetweenVectorsCos(movingTarget.position)
            let angleSin = lastposition.angleBetweenVectorsSin(movingTarget.position)
            SCNTransaction.begin()
            SCNTransaction.animationDuration = 0.5
            xDegree += angleSin
            yDegree += angleCos
            zDegree += 0

            if vMove {
                cube.eulerAngles.x =  xDegree
            }
            if hMove {
                cube.eulerAngles.y =  -yDegree
            }


            SCNTransaction.commit()
            lastposition = movingTarget.position
            .......    
            rotationTimer = time + 0.2
        }

    }

如何获得vMove(垂直移动)和hMove(水平移动) - 仅通过检测距离原点的距离来计算移动对象在哪个表面。

我为此做了一个完整的github回购。 See this and suggest some improvements