
円形のプレートでパッチワークなボールを表示するiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(hue: 0, saturation: 0.4, brightness: 1, alpha: 1)
self.setupScene()
self.createPatchBall()
self.createCamera()
self.createLight()
}
func setupScene() {
let w = CGRectGetMaxX(self.view.bounds)
let sv = SCNView(frame: CGRect(x: 0, y: 0, width: w, height: w))
sv.backgroundColor = UIColor(hue: 0, saturation: 0.3, brightness: 1, alpha: 1);
sv.scene = SCNScene()
self.view.addSubview(sv);
self.sceneView = sv;
}
func createPatchBall() {
let ball = SCNNode()
ball.name = “ball”
self.sceneView?.scene?.rootNode.addChildNode(ball)
let dAngle = 2.0 * Double(M_PI) / 10.0
let radius = 20.0
let baseLength = 2.0 * Double(M_PI) * radius / 10.0
for phi in 0..<5 {
let p = dAngle * Double(phi)
let cnt = 2.0 * Double(M_PI) * radius * sin(p) / baseLength
let adjLength = 2.0 * Double(M_PI) * radius * sin(p) / floor(cnt)
for theta in 0..<Int(cnt) {
let t = (2.0 * Double(M_PI) / floor(cnt)) * Double(theta)
let x = radius * cos(t)
let z = radius * sin(t)
let axis = SCNVector3(x: Float(x), y: 0, z: Float(z))
let panel = SCNCylinder(radius: CGFloat(adjLength)/2.0, height: 1)
panel.firstMaterial?.diffuse.contents = UIColor.whiteColor()
let panelNode = SCNNode(geometry: panel)
panelNode.name = “panel”
panelNode.transform = SCNMatrix4Translate(panelNode.transform, 0, Float(radius), 0)
panelNode.transform = SCNMatrix4Rotate(panelNode.transform, Float(p), axis.x, axis.y, axis.z)
ball.addChildNode(panelNode)
}
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.camera?.zFar = 2000
camera.position = SCNVector3(x: 0, y: 0, z: 60)
self.sceneView?.scene?.rootNode.addChildNode(camera)
}
func createLight() {
let light = SCNLight()
light.type = SCNLightTypeOmni
let lightNode = SCNNode()
lightNode.light = light
lightNode.position = SCNVector3(x: 0, y: 5, z: 50)
self.sceneView?.scene?.rootNode.addChildNode(lightNode)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let p = touches.anyObject()!.locationInView(self.sceneView)
if let hit = self.sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey : true])?.first as? SCNHitTestResult {
if hit.node.name == “panel” {
hit.node.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 1, y: 0, z: 0), duration: 0.5))
let hue = CGFloat(arc4random() % 10) * 0.1
hit.node.geometry?.firstMaterial?.diffuse.contents = UIColor(hue: hue, saturation: 0.4, brightness: 1, alpha: 1)
}
}
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
if let ball = self.sceneView?.scene?.rootNode.childNodeWithName(“ball”, recursively: false) {
ball.transform = SCNMatrix4Rotate(ball.transform, 0.1, 0, 1, 0)
}
}
}