Skip to content

Instantly share code, notes, and snippets.

@otmb

otmb/README.md Secret

Last active March 5, 2020 12:07
How to draw a line between two points in SceneKit (eulerAngle and quaternion)
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
import SceneKit
class MyViewController : UIViewController {
override func loadView() {
let scnView = SCNView()
scnView.delegate = self as? SCNSceneRendererDelegate
scnView.isPlaying = true
let scene = SCNScene()
scnView.backgroundColor = UIColor.gray
scnView.allowsCameraControl = true
scnView.scene = scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
scene.rootNode.addChildNode(cameraNode)
let from = simd_float3(x: -1, y: 5, z: 0)
let to = simd_float3(x: 0, y: 0, z: 2)
for pos in [from, to] {
let sphere = SCNSphere(radius: 0.2)
let sphereNode = SCNNode(geometry: sphere)
sphereNode.simdPosition = pos
scene.rootNode.addChildNode(sphereNode)
}
let cylinderNode1 = SCNNode(geometry: SCNCylinder())
scene.rootNode.addChildNode(cylinderNode1)
eulerAngle(node: cylinderNode1, from: from,to: to)
let cylinderNode2 = SCNNode(geometry: SCNCylinder())
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
cylinderNode2.geometry?.firstMaterial = material
scene.rootNode.addChildNode(cylinderNode2)
quaternion(node: cylinderNode2, from: from,to: to)
self.view = scnView
}
func eulerAngle(node: SCNNode,
from: simd_float3, to: simd_float3){
node.simdPosition = (from + to) / 2
let distance = simd_distance(from,to)
let cylinder = node.geometry as! SCNCylinder
cylinder.radius = 0.2
cylinder.height = CGFloat(distance)
let eulerAngles
= simd_float3(Float.pi / 2,
acos((to.z-from.z)/distance),
atan2((to.y-from.y),(to.x-from.x)))
node.simdEulerAngles = eulerAngles
}
func quaternion(node: SCNNode,
from: simd_float3, to: simd_float3){
node.simdPosition = (from + to) / 2
let distance = simd_distance(from,to)
let cylinder = node.geometry as! SCNCylinder
cylinder.radius = 0.2
cylinder.height = CGFloat(distance)
let vector = to - from
let height = simd_length(vector)
let line_axis = simd_float3(0, height/2, 0)
let vector_cross = simd_cross(line_axis, vector)
let qw = simd_length(line_axis) * simd_length(vector) + simd_dot(line_axis, vector)
let q = simd_quatf(ix: vector_cross.x, iy: vector_cross.y,
iz: vector_cross.z, r: qw).normalized
node.simdOrientation = q
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment