首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取用于创建SCNSphere的SCNNode的半径

获取用于创建SCNSphere的SCNNode的半径
EN

Stack Overflow用户
提问于 2014-11-11 21:33:57
回答 2查看 1.4K关注 0票数 2

如何返回用于设置SCNSphere的球面几何( SCNNode )的半径。我想在一种方法中使用radius,在这种方法中,我会相对于父节点移动一些子节点。下面的代码失败了,因为radius对于结果节点似乎是未知的,我不应该将节点传递给方法吗?

此外,我的数组索引失败,说明Int不是一个范围。

我正试着用来构建一些东西

代码语言:javascript
复制
import UIKit
import SceneKit

class PrimitivesScene: SCNScene {

    override init() {
        super.init()
        self.addSpheres();
    }

    func addSpheres() {
        let sphereGeometry = SCNSphere(radius: 1.0)
        sphereGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
        let sphereNode = SCNNode(geometry: sphereGeometry)
        self.rootNode.addChildNode(sphereNode)

        let secondSphereGeometry = SCNSphere(radius: 0.5)
        secondSphereGeometry.firstMaterial?.diffuse.contents = UIColor.greenColor()
        let secondSphereNode = SCNNode(geometry: secondSphereGeometry)
        secondSphereNode.position = SCNVector3(x: 0, y: 1.25, z: 0.0)

        self.rootNode.addChildNode(secondSphereNode)
        self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)
    }

    func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
        let parentRadius = parent.geometry.radius //This fails cause geometry does not know radius.

        for var index = 0; index < 3; ++index{
            children[index].position=SCNVector3(x:Float(index),y:parentRadius+children[index].radius/2, z:0);// fails saying int is not convertible to range.
        }


    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-11 22:21:45

radius的问题是,parent.geometry返回一个SCNGeometry,而不是一个SCNSphere。如果您需要获得radius,则需要先将parent.geometry转换为SCNSphere。为了安全起见,最好使用一些可选的绑定和链接来做到这一点:

代码语言:javascript
复制
if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
    // use parentRadius here
}

在访问radius节点上的children时,还需要这样做。如果你把所有这些都放在一起,把东西清理一下,你就会得到这样的东西:

代码语言:javascript
复制
func attachChildrenWithAngle(parent: SCNNode, children:[SCNNode], angle:Int) {
    if let parentRadius = (parent.geometry as? SCNSphere)?.radius {
        for var index = 0; index < 3; ++index{
            let child = children[index]
            if let childRadius = (child.geometry as? SCNSphere)?.radius {
                let radius = parentRadius + childRadius / 2.0
                child.position = SCNVector3(x:CGFloat(index), y:radius, z:0.0);
            }
        }
    }
}

但是请注意,您使用的是一个由两个子数组组成的数组来调用attachChildrenWithAngle

代码语言:javascript
复制
self.attachChildrenWithAngle(sphereNode, children:[secondSphereNode, sphereNode], angle:20)

如果这样做,在访问第三个元素时,for循环中将出现运行时崩溃。每次调用该函数时,您都需要传递一个带有3个子函数的数组,或者更改for循环中的逻辑。

票数 5
EN

Stack Overflow用户

发布于 2021-02-02 13:29:15

在这一点上,我只处理球体,因此半径很容易操作。但是,我仍然认为你应该试着看一下 SCNNode的几何结构。除了您发布的代码片段之外,我还使用了这个函数(这两个函数在一起很好)。

代码语言:javascript
复制
func updateRadiusOfNode(_ node: SCNNode, to radius: CGFloat) {
    if let sphere = (node.geometry as? SCNSphere) {
        if (sphere.radius != radius) {
            sphere.radius = radius
        }
    }
}

此外,标度因子(半径)也很重要。我使用一个baseRadius,然后我将它与

代码语言:javascript
复制
maxDistanceObserved / 2

如果hitTest有进一步的结果,则总是更新最大距离。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26874990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档