Skip to content

Instantly share code, notes, and snippets.

@GrantMeStrength
Last active March 17, 2024 12:19
Show Gist options
  • Save GrantMeStrength/62364f8a5d7ea26e2b97b37207459a10 to your computer and use it in GitHub Desktop.
Save GrantMeStrength/62364f8a5d7ea26e2b97b37207459a10 to your computer and use it in GitHub Desktop.
Drawing a line between two points in SceneKit / iOS / Swift
func line(from p1: SCNVector3, to p2: SCNVector3) -> SCNNode? {
// Draw a line between two points and return it as a node
var indices = [Int32(0), Int32(1)]
let positions = [p1, p2]
let vertexSource = SCNGeometrySource(vertices: positions)
let indexData = Data(bytes: &indices, count:MemoryLayout<Int32>.size * indices.count)
let element = SCNGeometryElement(data: indexData, primitiveType: .line, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size)
let line = SCNGeometry(sources: [vertexSource], elements: [element])
let lineNode = SCNNode(geometry: line)
return lineNode
}
// Draws a (very thin) line between two points.
// Not sure how to set the color though - materials didn't seem to do much
@atrbx5
Copy link

atrbx5 commented May 20, 2019

Have faced this issue few years ago and still not find a solution that fit visual requirements:
-have fixed on screen width (e.g. 2px or 3px)
-line width independant to perspective camera transformation

@Nirajpaul2
Copy link

func lineBetweenNodes(positionA: SCNVector3, positionB: SCNVector3, inScene: SCNScene) -> SCNNode {
        let vector = SCNVector3(positionA.x - positionB.x, positionA.y - positionB.y, positionA.z - positionB.z)
        let distance = sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
        let midPosition = SCNVector3 (x:(positionA.x + positionB.x) / 2, y:(positionA.y + positionB.y) / 2, z:(positionA.z + positionB.z) / 2)

        let lineGeometry = SCNCylinder()
        lineGeometry.radius = 0.002
        lineGeometry.height = CGFloat(distance)
        lineGeometry.radialSegmentCount = 5
        lineGeometry.firstMaterial!.diffuse.contents = UIColor.green

        let lineNode = SCNNode(geometry: lineGeometry)
        lineNode.position = midPosition
        lineNode.look (at: positionB, up: inScene.rootNode.worldUp, localFront: lineNode.worldUp)
        return lineNode
    }

How to use:

 let node = lineBetweenNodes(positionA: start.position, positionB: end.position, inScene: sceneView.scene)
     sceneView.scene.rootNode.addChildNode(node)

@bialylis
Copy link

bialylis commented Mar 9, 2020

I have developed a simple project that allows drawing any width and color line through multiple points. It also supports loops and mittered (sharp) joins. https://github.com/bialylis/ThickRedLine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment