Draw SceneKit object between two points

前端 未结 7 1980
别跟我提以往
别跟我提以往 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:33

    For the sake of another method, I achieved this through trigonometry. This made the code very minimal. Here is the end result:

    In my case the nodes are always placed on a fixed plane that slices the Y-Axis.

    // Create Cylinder Geometry                    
    let line = SCNCylinder(radius: 0.002, height: node1.distance(to: node2))
    
    // Create Material 
    let material = SCNMaterial()
    material.diffuse.contents = UIColor.red
    material.lightingModel = .phong
    line.materials = [material]
    
    // Create Cylinder(line) Node                   
    let newLine = SCNNode()
    newLine.geometry = line
    newLine.position = posBetween(first: node1, second: node2)
    
    // This is the change in x,y and z between node1 and node2
    let dirVector = SCNVector3Make(node2.x - node1.x, node2.y - node1.y, node2.z - node1.z)
    
    // Get Y rotation in radians
    let yAngle = atan(dirVector.x / dirVector.z)
    
    // Rotate cylinder node about X axis so cylinder is laying down
    currentLine.eulerAngles.x = .pi / 2
    
    // Rotate cylinder node about Y axis so cylinder is pointing to each node
    currentLine.eulerAngles.y = yAngle
    

    This is the function to get the position between two nodes, place it within your class:

    func posBetween(first: SCNVector3, second: SCNVector3) -> SCNVector3 {
            return SCNVector3Make((first.x + second.x) / 2, (first.y + second.y) / 2, (first.z + second.z) / 2)
    }
    

    This is the extension to get the distance between nodes for the cylinder height, place it somewhere outside of your class:

    extension SCNVector3 {
        func distance(to destination: SCNVector3) -> CGFloat {
            let dx = destination.x - x
            let dy = destination.y - y
            let dz = destination.z - z
            return CGFloat(sqrt(dx*dx + dy*dy + dz*dz))
        }
    }
    

    If you don't have one fixed axis like myself then you could do the extra trig to use this method.

提交回复
热议问题