将SCNNodes排列成圆形

4

我正在自动创建多个节点,希望能够将它们围绕在我周围排列,因为目前我只是在增加当前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

问题是,我如何让它们都在我周围而不仅仅是在一条线上?

你们中有人有这方面的数学函数吗?谢谢!


我看到了 https://dev59.com/m10a5IYBdhLWcg3wqaRS#40596990 这个问题,感觉这是你可以用来获取圆形位置的东西。基本上,你可以使用贝塞尔路径创建一个圆形,然后选择你想要放置它们的某些点。 - Vollan
你有检查过我的 ARKIT 回答吗? - Prashant Tukadiya
我将尝试这两个答案。 - Pietro Messineo
@PietroMessineo 只需复制粘贴 func arrangeNode(nodes:[SCNNode]),将您的数组传递进去,完成。 - Prashant Tukadiya
2个回答

2

使用以下代码(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)
}

enter image description here


非常感谢!我现在有一个问题,如果我有超过12个元素,我需要修改哪些参数?例如,我有90个元素要在我周围显示。 - Pietro Messineo
1
for-in 循环更改为 1...90。并且度数:sphereNode.rotation = SCNVector4(0, 1, 0, N。N 必须等于 4 度(将其转换为弧度)。 - Andy Jazz
我还没有得到它,N可能只是:(-CGFloat.pi * CGFloat(i))/(90/2)? - Pietro Messineo
1
看一下这张图片。使用分子和分母进行计算))) - Andy Jazz

1

你需要一些数学知识

我是如何准备圆形节点的

    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),或者在随机位置提供值。输出结果为:

enter image description here enter image description here

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接