iPhoneリバースパースペクティブ

錯視の一種リバースパースペクティブを表示するiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createTrapezoid()

        createCamera()

    }

    

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.scene = SCNScene()

        sv.backgroundColor = UIColor.blueColor()

        sv.allowsCameraControl = true

        view.addSubview(sv)

        sceneView = sv

    }

    

    func createTrapezoid() {

        let path = UIBezierPath()

        path.moveToPoint(CGPoint(x: –5, y: –10))

        path.addLineToPoint(CGPoint(x: 5, y: –6))

        path.addLineToPoint(CGPoint(x: 5, y: 6))

        path.addLineToPoint(CGPoint(x: –5, y: 10))

        path.closePath()

        

        

        [Int](07).each { i in

            let t = SCNShape(path: path, extrusionDepth: 0.1)

            t.firstMaterial?.diffuse.contents = (i % 2 == 0)

                ? UIColor(hue: 0.15, saturation: 1, brightness: 1, alpha: 1)

                : UIColor(hue: 0.15, saturation: 1, brightness: 0.5, alpha: 1)

            let tNode = SCNNode(geometry: t)

            tNode.transform = (i % 2 == 0)

                ? SCNMatrix4Rotate(tNode.transform, 0.8, 0, –1, 0)

                : SCNMatrix4Rotate(tNode.transform, Float(M_PI) – 0.8, 0, –1, 0)

            tNode.transform = SCNMatrix4Translate(tNode.transform, –Float(i) * 7.0, 0, 0)

            self.sceneView?.scene?.rootNode.addChildNode(tNode)

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.name = “camera”

        camera.camera = SCNCamera()

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

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

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let camera = sceneView?.scene?.rootNode.childNodeWithName(“camera”, recursively: false)

        camera?.runAction(SCNAction.moveByX(-20, y: 0, z: 0, duration: 10))

    }

}

extension Array {

    func each(doit:T->Void) {for i in self { doit(i) }}

}