Swift SCNNode 3D立方体旋转到立方体上的一点
Swift SCNNode 3D cube rotate to a point on cube
问题:尝试将立方体旋转到立方体本身上的一点。该点是随机创建的,它应该出现在屏幕中央。
尝试使用 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,distance from center])——然后是 cube.eulerAngles = deviation
在 func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
。但是立方体随机旋转。
我想出了一个简单的 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
问题:尝试将立方体旋转到立方体本身上的一点。该点是随机创建的,它应该出现在屏幕中央。
尝试使用 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,distance from center])——然后是 cube.eulerAngles = deviation
在 func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval)
。但是立方体随机旋转。
我想出了一个简单的 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