我想学习Clojure,并从使用quil的Mandelbrot生成器开始,我让它开始工作了——但是生成图像需要一些时间,而且占用了大量资源。关于如何使其更快的任何建议,或者如果您发现我的代码中有任何非clojure风格的部分。
Core.clj
(ns frac.core
(:require [quil.core :as q])
(:require [frac.complex :refer :all]))
(def scale (atom 0.01))
(def xoff (atom -200))
(def yoff (atom -200))
(def its 50)
(defn mandelbrot [r i]
(count (take its (take-while #(<= (modu %) 2) (iterate #( add (mul % %) [r i]) [r i])))))
(defn gen []
(let [p (q/pixels)
w (q/width)
h (q/height)]
(doseq [x (range w) y (range h)]
(let [m (mandelbrot (* @scale (+ x @xoff)) (* @scale (+ y @yoff)))
c (if (= m its) 0 m)]
(aset p (+ x (* y w)) (q/color (* 1.5 c) (* 4 c) (* 5.2 c))))))
(q/update-pixels))
(defn setup []
(gen))
(defn draw [])
(defn click []
(swap! xoff #(+ (q/mouse-x) (- (/ (q/width) 2)) %))
(swap! yoff #(+ (q/mouse-y) (- (/ (q/height) 2)) %))
(gen))
(defn wheel [z]
(swap! scale #(if (pos? z) (* 1.1 %) (* 0.9 %)))
(prn @scale)
(gen))
(q/defsketch example
:title "Mandel"
:setup setup
:draw draw
:size [400 400]
:mouse-clicked click
:mouse-wheel wheel)
(defn -main [& args])
Complex.clj
(ns frac.complex)
(defn mul [z1 z2]
(let [r1 (first z1)
i1 (second z1)
r2 (first z2)
i2 (second z2)]
[(- (* r1 r2) (* i1 i2)) (+ (* r1 i2) (* r2 i1))]))
(defn add [z1 z2]
(let [r1 (first z1)
i1 (second z1)
r2 (first z2)
i2 (second z2)]
[(+ r1 r2) (+ i1 i2)]))
(defn modu [z]
(let [r (first z)
i (second z)]
(Math/sqrt (+ (* r r) (* i i)))))
尝试设置此:
(set! *unchecked-math* :warn-on-boxed)
并删除所有警告。根据需要使用类型提示。