Swift의 Playground, 만델보에 집합


예전에소개의
만델보가 XCode7에 모여서 움직일 수 없으니 스위프트를 배우면서 해보자.

방법


1. XCode7을 시작하여 iOS 설정으로 Playground를 만듭니다.
2. Sources 폴더에 swift 파일을 적절히 만들어 다음 내용을 붙여넣습니다.
mandelbrot.swift
import UIKit

let resolution = 400
let iteration = 300

struct vec2{
  var x: Double
  var y: Double

  func length() -> Double{
   return sqrt(pow(x,2)+pow(y,2))
  }
}

func + (left:vec2,right:vec2) -> vec2{
  return vec2(x:(left.x + right.x),y:(left.y + right.y))
}

struct Result{
  var div: Bool//発散したかどうか
  var elapsed: Int?//発散した場合の計算回数
}

/// 結果格納クラス
public class ResultArray{
  var array: [Result]
  init(){
    self.array = Array(
      count:resolution * resolution,
      repeatedValue:Result(div: false,elapsed: nil)
    )
  }

  func indexIsValid(x:Int,y:Int)->Bool{
    return x>=0 && x<resolution && y>=0 && y<resolution
  }

  subscript(x:Int,y:Int) -> Result{
    get{
      assert(indexIsValid(x, y:y))
      return array[x * resolution + y]
    }
    set{
      assert(indexIsValid(x, y:y))
      array[x * resolution + y] = newValue
    }
  }
}

/// 複素数座標上の発散を計算
/// - parameter c :複素数座標
/// - returns: 発散の計算結果
func calcDiv(c:vec2) -> Result{
  var result:Result = Result(div:false,elapsed:nil)
  var z = vec2(x:0.0,y:0.0)
  for i in 0..<iteration{
    let nz = vec2(
      x: pow(z.x,2.0) - pow(z.y,2.0),
      y: 2.0 * z.x * z.y
    )
    z = nz + c
    if z.length() > 2.0{
      result = Result(div: true, elapsed: i)
      break
    }
  }
  return result
}

/// マンデルブロ集合の計算
/// - returns: 計算結果
public func calc() -> ResultArray{
  let result=ResultArray()
  for i in 0..<resolution{
    for j in 0..<resolution{
      let c = vec2(
        x: Double(i)/Double(resolution)*4.0-2.0,
        y: (Double(j)/Double(resolution)*4.0-2.0) * (-1)
      )
      result[i,j] = calcDiv(c)
    }
  }
  return result
}

/// マンデルブロ集合の描画
/// - parameters result: 計算結果
/// - returns : 描画データ
public func draw(result:ResultArray) -> UIView{
  let size = CGSize(width: resolution, height: resolution)
  let view = UIView(frame: CGRect(origin:CGPointZero, size: size))
  view.backgroundColor=UIColor(white:0.9,alpha:1.0)
  UIGraphicsBeginImageContextWithOptions(size, false,0)
  for i in 0..<resolution{
    for j in 0..<resolution{
      let rect = CGRectMake(CGFloat(i * 1), CGFloat(j * 1), 1, 1)
      let component: [CGFloat] = {
        if(result[i,j].div){
          let e: CGFloat = CGFloat(Float(result[i,j].elapsed!)*2.0/Float(iteration))
          return [1.0,1.0-e,1.0-e,1.0]
        }else{
          return [0.0,0.0,0.0,1.0]
        }
      }()
      let color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), component)!
      UIColor(CGColor: color).setFill()
      UIRectFill(rect)
    }
  }
  let image = UIGraphicsGetImageFromCurrentImageContext().CGImage
  view.layer.contents = image
  return view
}
3. Playground의 원본 파일에 다음 내용 붙여넣기
Content.swift
//: ## Mandelbrot Set
let result = calc()
draw(result)
4. 편집기 오른쪽에 있는 두 바퀴를 누르고 조금만 기다리면 화면이 나온다.

좋은 웹페이지 즐겨찾기