Created
October 29, 2017 09:56
-
-
Save mvarela/19b0cfae8d2ba343d469faf22bbcc1df to your computer and use it in GitHub Desktop.
De Jong attractors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ifs.de-jong | |
(:require [clojure.core.matrix :as m] | |
[com.evocomputing.colors :as c] | |
[clojure.core.matrix.stats :as mstats]) | |
(:import [java.io File] | |
[javax.imageio ImageIO] | |
[java.awt Color] | |
[java.awt.image | |
BufferedImage])) | |
(defn- next-point [coeffs [x y]] | |
(let [[a b c d] coeffs | |
xn (- (Math/sin (* y a)) (Math/cos (* x b))) | |
yn (- (Math/sin (* c x)) (Math/cos (* d y)))] | |
[xn yn])) | |
(defn- create-mapping [size] | |
(let [scale-and-bin (fn [[x y]] (let [mult (/ size 4) | |
xform (fn [i] (int (* mult (+ 2 i)))) | |
xx (xform x) | |
yy (xform y)] | |
[xx yy]))] | |
scale-and-bin)) | |
(defn- de-jong | |
[coeffs size start-point num-iter] | |
(let [np (partial next-point coeffs) | |
points (take num-iter (iterate np start-point)) | |
hist (m/new-matrix :vectorz (inc size) (inc size)) | |
scale (create-mapping size) | |
counter (fn [[x y]] | |
(m/mset! hist x y (inc (m/mget hist x y)))) | |
do-count (map (comp counter scale) points)] | |
(do (dorun do-count) | |
hist))) | |
(defn- shade-bw | |
"Value is normalized between 0 and 1, and it represents the density of points at | |
the position being considered" | |
[value] | |
(let [v (if (zero? value) 255 (int (* 255 value)))] | |
(bit-or (bit-shift-left v 16) | |
(bit-shift-left v 8) | |
v))) | |
(defn- shade-inverted | |
"Value is normalized between 0 and 1, and it represents the density of points at | |
the position being considered" | |
[value] | |
(let [vgamma (Math/pow value 1/2) | |
[r g b] (if (zero? vgamma) | |
[0 0 0] | |
;(c/hsl-to-rgb 245 60 (* 100 (- 1 vgamma ))))] | |
(c/hsl-to-rgb 245 30 (- 100 (* 50 (- 1 vgamma)))))] | |
(bit-or (bit-shift-left r 16) | |
(bit-shift-left g 8) | |
b))) | |
(defn- shade | |
"Value is normalized between 0 and 1, and it represents the density of points at | |
the position being considered" | |
[value] | |
(let [vgamma (Math/pow value 1/3) | |
v (if (zero? vgamma) | |
255 | |
(- 255 (int (* 255 vgamma))))] | |
(bit-or (bit-shift-left v 16) | |
(bit-shift-left v 8) | |
v))) | |
(defn- do-png [hist name shader] | |
(ImageIO/write | |
(let [size ((comp dec first) (m/shape hist)) | |
max-val (m/ereduce max 0 hist) | |
out (new BufferedImage size size BufferedImage/TYPE_3BYTE_BGR) | |
normalize (fn [x y] | |
(let [v (m/mget hist x y)] | |
(/ v max-val)))] | |
(doseq [x (range size) | |
y (range size)] | |
(.setRGB out x y (shader (normalize x y)))) | |
out) | |
"png" | |
(new File name))) | |
(defn do-de-jong [coeffs size num-iter shader] | |
(let [coeff-str (clojure.string/join "_" (map str coeffs)) | |
name (str "out-" coeff-str "-" (str size) "-" (str num-iter) ".png") | |
hist (de-jong coeffs size [0 0] num-iter)] | |
(do-png hist name shader))) | |
(do | |
(do-de-jong [0.970 -1.899 1.381 -1.506] 5000 5e6 shade-inverted) | |
(do-de-jong [1.4 -2.3 2.4 -2.1] 5000 5e6 shade-inverted) | |
(do-de-jong [-0.709 1.638 0.452 1.740] 5000 5e6 shade-inverted) | |
(do-de-jong [1.4191403 -2.2841523 2.4275403 -2.177196] 5000 5e6 shade-inverted) | |
(do-de-jong [1.02 -1.02 4 -4] 5000 5e6 shade-inverted) | |
(do-de-jong [1.4191403 -2.2841523 2.4275403 -2.177196] 2000 5e6 shade) | |
(do-de-jong [-1 4 -2 3] 2000 5e6 shade) | |
(do-de-jong [Math/PI (* -1 (/ Math/PI 6)) (* Math/PI 2) (- (Math/PI))] 2000 5e6 shade)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment