Draw SceneKit object between two points

前端 未结 7 2009
别跟我提以往
别跟我提以往 2020-12-07 23:51

Having made some progress in the geometry side of things I\'m moving on to putting together an entire scene. That scene has a couple dozen objects, each defined by a boundin

7条回答
  •  生来不讨喜
    2020-12-08 00:22

    @maury-markowitz's answer worked for me, here is the latest (Swift4) version of it. To anyone working with SCNVector3 in Swift I can only recommend to add the +-*/ operator overloads somewhere in your code (e.g. from here).

    extension SCNNode {
        static func lineNode(from: SCNVector3, to: SCNVector3, radius: CGFloat = 0.25) -> SCNNode {
            let vector = to - from
            let height = vector.length()
            let cylinder = SCNCylinder(radius: radius, height: CGFloat(height))
            cylinder.radialSegmentCount = 4
            let node = SCNNode(geometry: cylinder)
            node.position = (to + from) / 2
            node.eulerAngles = SCNVector3.lineEulerAngles(vector: vector)
            return node
        }
    }
    
    extension SCNVector3 {
        static func lineEulerAngles(vector: SCNVector3) -> SCNVector3 {
            let height = vector.length()
            let lxz = sqrtf(vector.x * vector.x + vector.z * vector.z)
            let pitchB = vector.y < 0 ? Float.pi - asinf(lxz/height) : asinf(lxz/height)
            let pitch = vector.z == 0 ? pitchB : sign(vector.z) * pitchB
    
            var yaw: Float = 0
            if vector.x != 0 || vector.z != 0 {
                let inner = vector.x / (height * sinf(pitch))
                if inner > 1 || inner < -1 {
                    yaw = Float.pi / 2
                } else {
                    yaw = asinf(inner)
                }
            }
            return SCNVector3(CGFloat(pitch), CGFloat(yaw), 0)
        }
    }
    

提交回复
热议问题