【问题标题】:Arrange SCNNodes in Circle将 SCNNode 排列成圆形
【发布时间】:2019-09-21 23:32:15
【问题描述】:

我正在自动创建多个节点,并且我想将它们安排在我周围,因为目前我只是将当前 X 位置增加了 0.1。

capsuleNode.geometry?.firstMaterial?.diffuse.contents = imageView
capsuleNode.position = SCNVector3(self.counterX, self.counterY, self.counterZ)
capsuleNode.name = topic.name
self.sceneLocationView.scene.rootNode.addChildNode(capsuleNode)
self.counterX += 0.1

所以问题是,我怎样才能让所有这些都在我身边,而不是只在一条线上?

你们中有人对此有一些数学函数吗?谢谢!

【问题讨论】:

  • 我看到stackoverflow.com/questions/30064816/… 感觉就像你可以用来获取圆的位置的东西。基本上你用贝塞尔路径创建一个圆,然后你可以选择你想要放置它们的某些点
  • 你检查我的 ARKIT 答案了吗?
  • 我将尝试两个答案
  • @PietroMessineo 只需复制粘贴 func arrangeNode(nodes:[SCNNode]) 传递您的数组即可完成

标签: swift scenekit augmented-reality arkit scnnode


【解决方案1】:

使用此代码(macOS 版本)进行测试:

import SceneKit

class GameViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()
        let scnView = self.view as! SCNView
        scnView.scene = scene
        scnView.allowsCameraControl = true
        scnView.backgroundColor = NSColor.black

        for i in 1...12 {  // HERE ARE 12 SPHERES

            let sphereNode = SCNNode(geometry: SCNSphere(radius: 1))
            sphereNode.position = SCNVector3(0, 0, 0)

            // ROTATE ABOUT THIS OFFSET PIVOT POINT
            sphereNode.simdPivot.columns.3.x = 5
            sphereNode.geometry?.firstMaterial?.diffuse.contents = NSColor(calibratedHue: CGFloat(i)/12, 
                                                                              saturation: 1, 
                                                                              brightness: 1,                
                                                                                   alpha: 1)

            // ROTATE ABOUT Y AXIS (STEP is 30 DEGREES EXPRESSED IN RADIANS)
            sphereNode.rotation = SCNVector4(0, 1, 0, (-CGFloat.pi * CGFloat(i))/6)
            scene.rootNode.addChildNode(sphereNode)
        }
    }
}

附:下面是创建 90 个球体的代码:

for i in 1...90 {

    let sphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
    sphereNode.position = SCNVector3(0, 0, 0)
    sphereNode.simdPivot.columns.3.x = 5
    sphereNode.geometry?.firstMaterial?.diffuse.contents = NSColor(calibratedHue: CGFloat(i)/90, saturation: 1, brightness: 1, alpha: 1)
    sphereNode.rotation = SCNVector4(0, 1, 0, (-CGFloat.pi * (CGFloat(i))/6)/7.5)
    scene.rootNode.addChildNode(sphereNode)
}

【讨论】:

  • 非常感谢!!我现在有一个问题,如果我有超过12个元素,我需要修改哪些参数?例如,我有 90 个元素要显示在我周围
  • for-in 循环更改为1...90。和度数:`sphereNode.rotation = SCNVector4(0, 1, 0, N`。N 必须等于 4 度(以弧度转换)。
  • 我没弄明白,N 可能只是:(-CGFloat.pi * CGFloat(i))/(90/2) ?
  • 看图。使用分子和分母)))
【解决方案2】:

这里需要一些数学运算

我如何准备圆形节点

    var nodes = [SCNNode]()
    for i in  1...20 {
        let node = createSphereNode(withRadius: 0.05, color: .yellow)
        nodes.append(node)
        node.position = SCNVector3(0,0,-1 * 1 / i)
        scene.rootNode.addChildNode(node)
    }

    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
        self.arrangeNode(nodes: nodes)
    }


   func createSphereNode(withRadius radius: CGFloat, color: UIColor) -> SCNNode {
        let geometry = SCNSphere(radius: radius)
        geometry.firstMaterial?.diffuse.contents = color
        let sphereNode = SCNNode(geometry: geometry)
        return sphereNode
   }

后面的数学把视图排列成圆圈

func arrangeNode(nodes:[SCNNode]) {

        let radius:CGFloat = 1;

        let angleStep = 2.0 * CGFloat.pi / CGFloat(nodes.count)

        var count:Int = 0

        for node in nodes {
            let xPos:CGFloat = CGFloat(self.sceneView.pointOfView?.position.x ?? 0) + CGFloat(cosf(Float(angleStep) * Float(count))) * (radius - 0)
            let zPos:CGFloat = CGFloat(self.sceneView.pointOfView?.position.z ?? 0) + CGFloat(sinf(Float(angleStep) * Float(count))) * (radius - 0)

            node.position = SCNVector3(xPos, 0, zPos)

            count = count + 1
        }


    }

注意:在第三张图片中我设置了。

            let xPos:CGFloat =  -1 + CGFloat(cosf(Float(angleStep) * Float(count))) * (radius - 0)
            let zPos:CGFloat = -1 + CGFloat(sinf(Float(angleStep) * Float(count))) * (radius - 0)

这意味着如果您需要在相机周围查看,那么

使用CGFloat(self.sceneView.pointOfView?.position.x ?? 0) 或在随机位置然后提供值

输出

【讨论】:

    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多