ルーローの三角形を表示するiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createCircle()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor(hue: 0.7, saturation: 0.1, brightness: 1, alpha: 1)
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createCircle() {
for i in 0…2 {
let c = SCNTube(innerRadius: 3, outerRadius: 3.1, height: 1)
c.firstMaterial?.diffuse.contents = UIColor.darkGrayColor()
let cNode = SCNNode(geometry: c)
cNode.name = “circle \(i)”
sceneView?.scene?.rootNode.addChildNode(cNode)
if i == 1{
let x = 3.0 * sin(M_PI/6.0)
let z = 3.0 * cos(M_PI/6.0)
cNode.runAction(SCNAction.moveTo(SCNVector3(x: Float(x), y: 0 , z: Float(z)), duration: 1.0))
}
if i == 2{
let x = 3.0 * sin(M_PI/6.0)
let z = 3.0 * cos(M_PI/6.0)
cNode.runAction(SCNAction.moveTo(SCNVector3(x: –Float(x), y: 0 , z: Float(z)), duration: 1.0))
}
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if count++ > 0 {
return
}
let c0 = self.sceneView?.scene?.rootNode.childNodeWithName(“circle 0”, recursively: false)
let c1 = self.sceneView?.scene?.rootNode.childNodeWithName(“circle 1”, recursively: false)
let c2 = self.sceneView?.scene?.rootNode.childNodeWithName(“circle 2”, recursively: false)
let p = UIBezierPath()
var start : CGFloat = CGFloat(M_PI / 3.0)
var end : CGFloat = CGFloat(M_PI / 3.0) * 2.0
p.addArcWithCenter(CGPointMake(CGFloat(c0!.position.x), CGFloat(c0!.position.z)), radius: 3.0, startAngle: start, endAngle: end, clockwise: true)
start = start + CGFloat(M_PI / 1.5)
end = end + CGFloat(M_PI / 1.5)
p.addArcWithCenter(CGPointMake(CGFloat(c1!.position.x), CGFloat(c1!.position.z)), radius: 3.0, startAngle: start, endAngle: end, clockwise: true)
start += CGFloat(M_PI / 1.5)
end += CGFloat(M_PI / 1.5)
p.addArcWithCenter(CGPointMake(CGFloat(c2!.position.x), CGFloat(c2!.position.z)), radius: 3.0, startAngle: start, endAngle: end, clockwise: true)
start += CGFloat(M_PI / 1.5)
end += CGFloat(M_PI / 1.5)
p.flatness = 0.01
let reuleaux = SCNShape(path: p, extrusionDepth: 1)
reuleaux.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.5, brightness: 1, alpha: 1)
let reuleauxNode = SCNNode(geometry: reuleaux)
reuleauxNode.name = “reuleaux”
reuleauxNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI * 0.5))
reuleauxNode.physicsBody = SCNPhysicsBody.dynamicBody()
reuleauxNode.physicsBody?.physicsShape = SCNPhysicsShape(node: reuleauxNode, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron])
reuleauxNode.physicsBody?.restitution = 0
reuleauxNode.physicsBody?.friction = 0
sceneView?.scene?.rootNode.addChildNode(reuleauxNode)
reuleauxNode.physicsBody?.angularVelocityFactor = SCNVector3(x: 0, y: 1, z: 0)
reuleauxNode.physicsBody?.velocityFactor = SCNVector3(x: 1, y: 0, z: 1)
c0?.runAction(SCNAction.fadeOutWithDuration(2.0))
c1?.runAction(SCNAction.fadeOutWithDuration(2.0))
c2?.runAction(SCNAction.fadeOutWithDuration(2.0))
for i in 0…3 {
let bar = SCNBox(width: 3.2, height: 1, length: 0.1, chamferRadius: 0)
bar.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
let barNode = SCNNode(geometry: bar)
barNode.pivot = SCNMatrix4MakeTranslation(0, 0, –1.57)
barNode.position = SCNVector3(x: 0, y: 0, z: 1.57)
barNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(i) * Float(M_PI/2.0))
barNode.physicsBody = SCNPhysicsBody.staticBody()
barNode.physicsBody?.friction = 0
barNode.physicsBody?.restitution = 0
sceneView?.scene?.rootNode.addChildNode(barNode)
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 12, z: 1)
camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –Float(M_PI) * 0.5)
self.sceneView?.scene?.rootNode.addChildNode(camera)
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if let reuleaux = sceneView?.scene?.rootNode.childNodeWithName(“reuleaux”, recursively: false) {
reuleaux.physicsBody?.applyTorque(SCNVector4(x: 0, y: 1, z: 0, w: 1), impulse: true)
}
}
}