如何在Swift中筛选出z值为最小负数的SCNNode节点?
问题:选中z值绝对值最小的负数值节点
我有一组节点的SCNVector3坐标数据:
node 0 SCNVector3(x: 8.208711e-08, y: 0.0, z: -1.9389672) node 1 SCNVector3(x: -0.93896717, y: 0.0, z: -1.0000001) node 2 SCNVector3(x: -8.208711e-08, y: 0.0, z: -0.06103283) node 3 SCNVector3(x: 0.93896717, y: 0.0, z: -0.99999994) node 4 SCNVector3(x: 0.0, y: 0.93896717, z: -1.0) node 5 SCNVector3(x: 0.0, y: -0.93896717, z: -1.0)
我需要选中node2,因为它的z值是最小的负数(即绝对值最小的负数值)。以下是我当前的Swift代码,但无法正确实现需求:
struct Sats { var theNode = SCNNode() var theIndex:Int = 7 } if cubeNode != nil { cubeNode.enumerateChildNodes { (node, stop) in let search = /face(\d+)/ if let result = try? search.wholeMatch(in: node.name!) { print("node \(result.1) \(node.worldPosition) ") if node.worldPosition.z < -0.05 { print("eureka \(theOne.theIndex)") theOne.theNode = node theOne.theIndex = Int(result.1)! } } } }
问题分析
当前代码的判断条件node.worldPosition.z < -0.05仅筛选出z值小于-0.05的节点,但会在遍历到最后一个符合条件的节点时覆盖之前的结果,无法精准定位到z值最大的负数(即绝对值最小的负数)。比如node2的z值是-0.061,比其他符合条件的节点z值都大,本应被选中,但当前逻辑无法保证这一点。
解决方法
需要跟踪当前找到的最大z值(负数中数值越大,绝对值越小),初始时设置一个极小的负数作为基准,遍历每个节点时,若当前节点z值是负数且大于基准值,就更新选中的节点。
修正后的代码:
struct Sats { var theNode: SCNNode? // 改为可选类型,避免默认空节点带来的无效值 var theIndex: Int = -1 } var theOne = Sats() var maxZValue = Double.negativeInfinity // 初始化为最小的负数,确保第一个符合条件的节点能被选中 if let cubeNode = cubeNode { cubeNode.enumerateChildNodes { (node, stop) in let search = /face(\d+)/ guard let result = try? search.wholeMatch(in: node.name ?? ""), let index = Int(result.1) else { return // 名称不匹配或索引转换失败时直接跳过 } let z = node.worldPosition.z print("node \(index) \(node.worldPosition) ") // 只考虑负数z值,且当前z值大于已记录的最大z值 if z < 0 && z > maxZValue { maxZValue = z theOne.theNode = node theOne.theIndex = index print("选中节点:\(index),z值:\(z)") } } }
代码说明
- 将
Sats中的theNode改为可选类型,避免初始值使用空的SCNNode,逻辑更严谨。 - 初始化
maxZValue为Double.negativeInfinity,确保第一个负数z值会被选中作为初始基准。 - 增加
guard语句验证节点名称匹配和索引转换的有效性,避免强制解包导致崩溃。 - 判断条件改为
z < 0 && z > maxZValue,精准筛选出负数中z值最大(绝对值最小)的节点。
内容的提问来源于stack exchange,提问作者user3069232
相关产品推荐
相关产品推荐

