Swift ARKit无法在垂直平面上正确旋转SCNNode
我想旋转一个SCNNode,它是一个绘画图像 我可以在地板上旋转它,但我不能在墙上正确旋转它 (我正在使用UIRotationGestureRecognitor)Swift ARKit无法在垂直平面上正确旋转SCNNode,swift,rotation,scenekit,augmented-reality,arkit,Swift,Rotation,Scenekit,Augmented Reality,Arkit,我想旋转一个SCNNode,它是一个绘画图像 我可以在地板上旋转它,但我不能在墙上正确旋转它 (我正在使用UIRotationGestureRecognitor) 有人知道如何在墙上正确旋转它吗?谢谢大家! 您正在代码中使用eulerAngles实例属性: var eulerAngles: SCNVector3 { get set } 根据苹果的文档: SceneKit按照组件的相反顺序应用相对于节点枢轴属性的eulerAngles旋转:首先roll(Z),然后yaw(Y),然后pitch(
有人知道如何在墙上正确旋转它吗?谢谢大家! 您正在代码中使用
eulerAngles
实例属性:
var eulerAngles: SCNVector3 { get set }
根据苹果的文档:
SceneKit按照组件的相反顺序应用相对于节点枢轴属性的eulerAngles
旋转:首先roll
(Z),然后yaw
(Y),然后pitch
(X)
…但三分量旋转可能导致。
常平架锁定是指当三个常平架中的两个轴被驱动成平行配置时,在三维、三个常平架机构中失去一个自由度,“锁定”系统,使其在退化的二维空间中旋转
因此,需要使用四分量旋转特性:
var rotation: SCNVector4 { get set }
指定前三个组件(XYZ)中旋转轴的方向,以及第四个组件(W)中以弧度表示的旋转角度
如果您想了解更多有关SCInvector4
结构和四分量旋转(及其以弧度表示的W分量)的信息,请查看和
p.S.
在RealityKit框架中而不是scinvector4
结构中,您需要使用SIMD4
通用结构或simd\u float4
类型别名
var rotation: simd_float4 { get set }
我尝试了SCNNode-eulerAngles
和SCNNode-rotation
但是我没有运气
我想这是因为我在添加绘画时调用了SCNNode.transform()
。当以后我修改SCNNode.euleranges
并调用SCNNode.rotation()
时,它们可能会对第一次变换产生影响
我最终通过使用SCNMatrix4Rotate
,而不是使用eulerAngles
和rotation
使它工作起来
func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
...
let newPaintingNode = SCNNode(geometry: planeGeometry)
newPaintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
newPaintingNode.transform = SCNMatrix4Rotate(newPaintingNode.transform, -Float.pi / 2.0, 1.0, 0.0, 0.0)
newPaintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
self.paintingNode = newPaintingNode
...
}
...
@objc func rotateNode(_ gesture: UIRotationGestureRecognizer){
if let _ = self.paintingNode {
// Get The Current Rotation From The Gesture
let rotation = Float(gesture.rotation)
if gesture.state == .began {
self.rotationZ = rotation
}
if gesture.state == .changed {
let diff = rotation - self.rotationZ
self.paintingNode?.transform = SCNMatrix4Rotate(self.paintingNode!.transform, diff, 0.0, 0.0, 1.0)
self.rotationZ = rotation
}
}
}
上述代码适用于垂直和水平面。谢谢您的回复!我尝试使用SConvector4,但结果仍然很奇怪。有时工作正常,有时不正常。我更改了rotateNode()
并添加了self.paintingNode?.rotation=scinvector4(x:0,y:0,z:1,w:currentAngleZ+rotation)
当self.paintingAlignment==“垂直”
时,您的w
值是弧度还是度?进行旋转时,您使用的是local
轴还是world
轴?并认为正<代码> z <代码>值为逆时针旋转(<代码> ccw < /代码>),而否定<代码> z <代码>值为时钟旋转(<代码> CW < /代码>)。谢谢您,并为迟来的答复表示歉意。我的w
值以弧度为单位。我不知道我使用的是local
axis还是world
axis。。。
var rotation: simd_float4 { get set }
func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
...
let newPaintingNode = SCNNode(geometry: planeGeometry)
newPaintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
newPaintingNode.transform = SCNMatrix4Rotate(newPaintingNode.transform, -Float.pi / 2.0, 1.0, 0.0, 0.0)
newPaintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
self.paintingNode = newPaintingNode
...
}
...
@objc func rotateNode(_ gesture: UIRotationGestureRecognizer){
if let _ = self.paintingNode {
// Get The Current Rotation From The Gesture
let rotation = Float(gesture.rotation)
if gesture.state == .began {
self.rotationZ = rotation
}
if gesture.state == .changed {
let diff = rotation - self.rotationZ
self.paintingNode?.transform = SCNMatrix4Rotate(self.paintingNode!.transform, diff, 0.0, 0.0, 1.0)
self.rotationZ = rotation
}
}
}