iPhoneルーローの三角

ルーローの三角形を表示する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 02 {

            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 03 {

            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)

        }

    }

}