ARImageAnchor 变换矩阵的坐标与 ARPlaneAnchor 的坐标相差太大
Coordinates of ARImageAnchor transform matrix are way too different from the ARPlaneAnchor ones
我正在做这件简单的事情:
- 垂直平面检测
- 垂直平面上的图像识别
图像挂在检测到的平面上(在我的墙上)。在这两种情况下,我都从 ARSCNViewDelegate
实现了 renderer:didAddNode:forAnchor:
函数。我站在垂直平面检测和图像识别的地方。
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let shipScene = SCNScene(named: "ship.scn"), let shipNode = shipScene.rootNode.childNode(withName: "ship", recursively: false) else { return }
shipNode.position = SCNVector3(anchor.transform.columns.3.x, anchor.transform.columns.3.y, anchor.transform.columns.3.z)
sceneView.scene.rootNode.addChildNode(shipNode)
print(anchor.transform)
}
在垂直平面检测的情况下,anchor
将是 ARPlaneAnchor
。在图像识别的情况下,anchor
将是 ARImageAnchor
.
为什么这两个锚点的变换矩阵如此不同?我正在打印 anchor.transform
并得到这些结果:
1.
simd_float4x4([
[0.941312, 0.0, -0.337538, 0.0)],
[0.336284, -0.0861278, 0.937814, 0.0)],
[-0.0290714,-0.996284, -0.0810731, 0.0)],
[0.191099, 0.172432, -1.14543, 1.0)]
])
2.
simd_float4x4([
[0.361231, 0.10894, 0.926093, 0.0)],
[-0.919883, -0.121052, 0.373049, 0.0)],
[0.152743, -0.986651, 0.0564843, 0.0)],
[75.4418, 10.9618, -14.3788, 1.0)]
])
所以如果我想在检测到的垂直平面上放置一个 3D 对象,我可以简单地使用 [x = 0.191099, y = 0.172432, z = -1.14543]
作为坐标来设置我的节点的位置 (myNode
),然后添加这个节点使用 sceneView.scene.rootNode.addChildNode(myNode)
到场景,但如果我想将 3D 对象放置在检测到的图像的锚点处,我不能使用 [x = 75.4418, y = 10.9618, z = -14.3788]
.
如何将 3D 对象放置在检测到的图像的锚点上? ARImageAnchor的变换矩阵我真的不懂
这是我使用 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
方法的示例:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
guard let currentImageAnchor = anchor as? ARImageAnchor else { return }
let x = currentImageAnchor.transform
print(x.columns.3.x, x.columns.3.y , x.columns.3.z)
//2. Get The Targets Name
let name = currentImageAnchor.referenceImage.name!
//3. Get The Targets Width & Height In Meters
let width = currentImageAnchor.referenceImage.physicalSize.width
let height = currentImageAnchor.referenceImage.physicalSize.height
print("""
Image Name = \(name)
Image Width = \(width)
Image Height = \(height)
""")
//4. Create A Plane Geometry To Cover The ARImageAnchor
let planeNode = SCNNode()
let planeGeometry = SCNPlane(width: width, height: height)
planeGeometry.firstMaterial?.diffuse.contents = UIColor.white
planeNode.opacity = 0.25
planeNode.geometry = planeGeometry
//5. Rotate The PlaneNode To Horizontal
planeNode.eulerAngles.x = -.pi/2
//The Node Is Centered In The Anchor (0,0,0)
node.addChildNode(planeNode)
//6. Create AN SCNBox
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
//7. Create A Different Colour For Each Face
let faceColours = [UIColor.red, UIColor.green, UIColor.blue, UIColor.cyan, UIColor.yellow, UIColor.gray]
var faceMaterials = [SCNMaterial]()
//8. Apply It To Each Face
for face in 0 ..< 5{
let material = SCNMaterial()
material.diffuse.contents = faceColours[face]
faceMaterials.append(material)
}
boxGeometry.materials = faceMaterials
boxNode.geometry = boxGeometry
//9. Set The Boxes Position To Be Placed On The Plane (node.x + box.height)
boxNode.position = SCNVector3(0 , 0.05, 0)
//10. Add The Box To The Node
node.addChildNode(boxNode)
}
根据我的理解(我当然可能错了)你会知道你的放置区域是 referenceImage.physicalSize
的宽度和高度,以米表示:
let width = currentImageAnchor.referenceImage.physicalSize.width
let height = currentImageAnchor.referenceImage.physicalSize.height
因此,您需要在这些边界内缩放您的内容(如果需要以适应),假设您希望它看起来覆盖图像。
我正在做这件简单的事情:
- 垂直平面检测
- 垂直平面上的图像识别
图像挂在检测到的平面上(在我的墙上)。在这两种情况下,我都从 ARSCNViewDelegate
实现了 renderer:didAddNode:forAnchor:
函数。我站在垂直平面检测和图像识别的地方。
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let shipScene = SCNScene(named: "ship.scn"), let shipNode = shipScene.rootNode.childNode(withName: "ship", recursively: false) else { return }
shipNode.position = SCNVector3(anchor.transform.columns.3.x, anchor.transform.columns.3.y, anchor.transform.columns.3.z)
sceneView.scene.rootNode.addChildNode(shipNode)
print(anchor.transform)
}
在垂直平面检测的情况下,anchor
将是 ARPlaneAnchor
。在图像识别的情况下,anchor
将是 ARImageAnchor
.
为什么这两个锚点的变换矩阵如此不同?我正在打印 anchor.transform
并得到这些结果:
1.
simd_float4x4([
[0.941312, 0.0, -0.337538, 0.0)],
[0.336284, -0.0861278, 0.937814, 0.0)],
[-0.0290714,-0.996284, -0.0810731, 0.0)],
[0.191099, 0.172432, -1.14543, 1.0)]
])
2.
simd_float4x4([
[0.361231, 0.10894, 0.926093, 0.0)],
[-0.919883, -0.121052, 0.373049, 0.0)],
[0.152743, -0.986651, 0.0564843, 0.0)],
[75.4418, 10.9618, -14.3788, 1.0)]
])
所以如果我想在检测到的垂直平面上放置一个 3D 对象,我可以简单地使用 [x = 0.191099, y = 0.172432, z = -1.14543]
作为坐标来设置我的节点的位置 (myNode
),然后添加这个节点使用 sceneView.scene.rootNode.addChildNode(myNode)
到场景,但如果我想将 3D 对象放置在检测到的图像的锚点处,我不能使用 [x = 75.4418, y = 10.9618, z = -14.3788]
.
如何将 3D 对象放置在检测到的图像的锚点上? ARImageAnchor的变换矩阵我真的不懂
这是我使用 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
方法的示例:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
guard let currentImageAnchor = anchor as? ARImageAnchor else { return }
let x = currentImageAnchor.transform
print(x.columns.3.x, x.columns.3.y , x.columns.3.z)
//2. Get The Targets Name
let name = currentImageAnchor.referenceImage.name!
//3. Get The Targets Width & Height In Meters
let width = currentImageAnchor.referenceImage.physicalSize.width
let height = currentImageAnchor.referenceImage.physicalSize.height
print("""
Image Name = \(name)
Image Width = \(width)
Image Height = \(height)
""")
//4. Create A Plane Geometry To Cover The ARImageAnchor
let planeNode = SCNNode()
let planeGeometry = SCNPlane(width: width, height: height)
planeGeometry.firstMaterial?.diffuse.contents = UIColor.white
planeNode.opacity = 0.25
planeNode.geometry = planeGeometry
//5. Rotate The PlaneNode To Horizontal
planeNode.eulerAngles.x = -.pi/2
//The Node Is Centered In The Anchor (0,0,0)
node.addChildNode(planeNode)
//6. Create AN SCNBox
let boxNode = SCNNode()
let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
//7. Create A Different Colour For Each Face
let faceColours = [UIColor.red, UIColor.green, UIColor.blue, UIColor.cyan, UIColor.yellow, UIColor.gray]
var faceMaterials = [SCNMaterial]()
//8. Apply It To Each Face
for face in 0 ..< 5{
let material = SCNMaterial()
material.diffuse.contents = faceColours[face]
faceMaterials.append(material)
}
boxGeometry.materials = faceMaterials
boxNode.geometry = boxGeometry
//9. Set The Boxes Position To Be Placed On The Plane (node.x + box.height)
boxNode.position = SCNVector3(0 , 0.05, 0)
//10. Add The Box To The Node
node.addChildNode(boxNode)
}
根据我的理解(我当然可能错了)你会知道你的放置区域是 referenceImage.physicalSize
的宽度和高度,以米表示:
let width = currentImageAnchor.referenceImage.physicalSize.width
let height = currentImageAnchor.referenceImage.physicalSize.height
因此,您需要在这些边界内缩放您的内容(如果需要以适应),假设您希望它看起来覆盖图像。