LoginSignup
5
6

More than 5 years have passed since last update.

「プログラムでシダを描画する」をClojureで描画する(リアルタイム描画)

Last updated at Posted at 2014-11-14

空前のシダ描画ブーム到来!?(^^;)
あなたも得意なプログラミング言語でシダを描画してみよう!

Clojure版は既出ですが、マルチスレッドでリアルタイムに描画するコードを書いてみました。
(バグとかご意見ありましたら https://twitter.com/akmiyoshi までお願いします)

2014-1114-1950.png

project.clj
(defproject sida "1.0.0"
  :main sida.core
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [quil "2.2.2"]])
src/sida/core.clj
(ns sida.core
  (:gen-class)
  (:require [quil.core :as quil]))

(def QUIL-WIDTH 500)
(def QUIL-HEIGHT 500)
(def PLOT-STEP 500)

(def quil-count (atom 0))
(def plot-count (atom 0))
(def plot-queue (new java.util.concurrent.ConcurrentLinkedQueue))

(defn setup []
  (quil/frame-rate 200) ;; 200 FPS
  (quil/no-smooth) ;; アンチエイリアスなし
  (quil/background 0 0 0) ;; 黒 ⇒ RGB(0,0,0)
  (quil/stroke 0 255 0) ;; 緑 ⇒ RGB(0,255,0)
  (quil/stroke-weight 1))

(defn draw []
  (let [$size (.size plot-queue)]
    (dotimes [_ $size]
      (let [[$x $y] (.poll plot-queue)]
        (quil/point
          (+ (* $x (quil/width) 0.98) (* (quil/width) 0.5))
          (- (quil/height) (* $y (quil/height) 0.98)))
        (swap! quil-count inc)))
    (when (> $size 0)
      (println "Draw-Thread: $size=" $size "(quil-count=" @quil-count ")"))))

(defn W1x [$x $y] (+ (* 0.836 $x) (* 0.044 $y)))
(defn W1y [$x $y] (+ (* -0.044 $x) (* 0.836 $y) 0.169))
(defn W2x [$x $y] (+ (* -0.141 $x) (* 0.302 $y)))
(defn W2y [$x $y] (+ (* 0.302 $x) (* 0.141 $y) 0.127))
(defn W3x [$x $y] (- (* 0.141 $x) (* 0.302 $y)))
(defn W3y [$x $y] (+ (* 0.302 $x) (* 0.141 $y) 0.169))
(defn W4x [$x $y] 0)
(defn W4y [$x $y] (* 0.175337 $y))

(defn plot [$x $y]
  (.add plot-queue (vector $x $y))
  (swap! plot-count inc)
  (cond
    (< @plot-count PLOT-STEP) (Thread/sleep 5)
    (= 0 (rem @plot-count PLOT-STEP)) (Thread/sleep 5)))

(defn f [$k $x $y]
  (cond
    (< 0 $k)
    (do
      (f (- $k 1) (W1x $x $y) (W1y $x $y))
      (when (< (rand) 0.3)
        (f (- $k 1) (W2x $x $y) (W2y $x $y)))
      (when (< (rand) 0.3)
        (f (- $k 1) (W3x $x $y) (W3y $x $y)))
      (when (< (rand) 0.3)
        (f (- $k 1) (W4x $x $y) (W4y $x $y)))
      )
    :else
    (plot $x $y)))

(defn -main [& args]
  ;; Start quil (draw) thread
  (quil/defsketch draw-thread
    :title "Sida in Clojure"
    :draw draw
    :setup setup
    :size [QUIL-WIDTH QUIL-HEIGHT]
    :features [:exit-on-close])
  (println "Main-Thread Start")
  (f 20 0 0)
  (println "Main-Thread End: plot-count=" @plot-count))
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6