iPhone紐で模様

紐で模様をつくるiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    var count = 0;

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createPin()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor.brownColor()

        sv.scene = SCNScene()

        sv.autoenablesDefaultLighting = true

        sv.allowsCameraControl = true

        view.addSubview(sv)

        

        sceneView = sv

    }

    func createPin() {

        let r = 5.0

        let dw = M_PI / 10.0

        for i in 020 {

            let pin = SCNSphere(radius: 0.2)

            pin.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()

            let pinNode = SCNNode(geometry: pin)

            pinNode.name = “pin \(i)”

            let x = r * cos(dw * Double(i))

            let y = r * sin(dw * Double(i))

            pinNode.position = SCNVector3(x: Float(x), y: Float(y), z: 0)

            sceneView?.scene?.rootNode.addChildNode(pinNode)

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.position = SCNVector3(x: 0, y: 0, z: 18)

        sceneView?.scene?.rootNode.addChildNode(camera)

    }

    

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        if (self.count > 10) {

            return

        }

        

        let num = 10

        let n0 = sceneView?.scene?.rootNode.childNodeWithName(“pin \(self.count)”, recursively: false)

        let n1 = sceneView?.scene?.rootNode.childNodeWithName(“pin \((self.count + num – 1) % 20)”, recursively: false)

        let n2 = sceneView?.scene?.rootNode.childNodeWithName(“pin \((self.count + num) % 20 )”, recursively: false)

        let n3 = sceneView?.scene?.rootNode.childNodeWithName(“pin \((self.count + num + 1) % 20)”, recursively: false)

        

        for n in [n1, n2, n3] {

            let geo = SCNCylinder(radius: 0.04, height: 0.1)

            geo.firstMaterial?.diffuse.contents = UIColor.purpleColor()

            let line = SCNNode(geometry: geo)

            line.pivot = SCNMatrix4MakeTranslation(0, –0.05, 0)

            line.position = n0!.position

            sceneView?.scene?.rootNode.addChildNode(line)

            

            var w = angle(n0!.position, v2: n!.position)

            if (count > 5 && count < 15) {

                w = w + Float(M_PI)

            }

            line.rotation = SCNVector4Make(0, 0, 1, w)

            

            let transform = line.transform

            line.runAction(SCNAction.customActionWithDuration(1.0, actionBlock: { (n, t) -> Void in

                n.transform = SCNMatrix4Scale(transform, 1, 1 + 100 * Float(t), 1)

            }))

        }

        

        ++count

    }

    

    func angle(v1 : SCNVector3, v2 : SCNVector3) -> Float {

        let dx = v2.x – v1.x

        let dy = v2.y – v1.y

        return atan(dy / dx) + Float(M_PI) * 0.5

    }

}