iPhone二重螺旋

DNAっぽい二重螺旋を表示するiPhoneアプリのサンプルコード

import UIKit

import SceneKit

class ViewController: UIViewController,SCNSceneRendererDelegate {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.scene = SCNScene()

        sv.backgroundColor = UIColor.blackColor()

        sv.allowsCameraControl = true

        sv.delegate = self

        view.addSubview(sv)

        sceneView = sv

    }

    

    func createHelix(i : Int) {

        let r : Float = 0.1

        let dw = Float(M_PI) / 50.0

        var w = dw * Float(i)

        var x = r * cos(w)

        var z = r * sin(w)

        let y = 0.01 * Float(i)

        let bar = SCNBox(width: 0.01, height: 0.05, length: 0.01, chamferRadius: 0)

        bar.firstMaterial?.diffuse.contents = UIColor.blueColor()

        let barNodeA = SCNNode(geometry: bar)

        barNodeA.position = SCNVector3(x: x, y: y, z: z)

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

        

        w = dw * Float(i) + Float(M_PI/3.0)

        x = r * cos(w)

        z = r * sin(w)

        let barB = SCNBox(width: 0.01, height: 0.05, length: 0.01, chamferRadius: 0)

        barB.firstMaterial?.diffuse.contents = UIColor.orangeColor()

        let barNodeB = SCNNode(geometry: barB)

        barNodeB.position = SCNVector3(x: x, y: y, z: z)

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

        

        

        if (i % 10 == 0) {

            var verts : [SCNVector3] = [barNodeA.position, barNodeB.position];

            let indices : [Int32] = [0, 1];

            

            let vertexSource = SCNGeometrySource(vertices:UnsafePointer<SCNVector3>(verts), count:verts.count);

            let indexData = NSData(bytes:indices, length:sizeof(Int32) * indices.count);

            let element = SCNGeometryElement(data:indexData, primitiveType:.Line, primitiveCount:indices.count, bytesPerIndex:sizeof(Int32));

            

            let line = SCNGeometry(sources:[vertexSource], elements:[element]);

            line.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.4, brightness: 1, alpha: 1)

            let lineNode = SCNNode(geometry:line);

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

        }

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

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

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

    }

    

    var count = 0

    

    func renderer(aRenderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: NSTimeInterval) {

        glLineWidth(4)

    }

    

    func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {

        if (count < 300) {

            self.createHelix(++count)

        }

        

    }

    

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

        sceneView?.playing = true

    }

}

extension Array {

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

}