<commit_before>;; http://www.algorithmic-worlds.net/blog/blog.php?Post=20110227
;; https://softologyblog.wordpress.com/2011/04/05/ducks-fractals/

;; Interactions, press:
;;
;; * n - new configuration and render
;; * z - zoom in
;; * x - zoom out
;; * SPACE - save image
;;
;; Click mouse to make new center point

(ns examples.ex34-ducks-kalisets
  (:require [clojure2d.core :refer :all]
            [clojure2d.math :as m]
            [clojure2d.math.complex :as c]
            [clojure2d.math.vector :as v]
            [clojure2d.pixels :as p]
            [clojure2d.math.random :as r]
            [clojure.pprint :refer :all])
  (:import [clojure2d.math.vector Vec2 Vec4]))

(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)

(def ^:const ^int w 800)
(def ^:const ^int h 800)

(def ^:const title "Ducks and Kalis")

(deftype Bounds [^double x1 ^double y1
                 ^double x2 ^double y2
                 ^double sx ^double sy]
  Object
  (toString [b] (str "[(" x1 ", " y1 "), (" x2 ", " y2 ")]")))

(defn make-bounds
  ""
  [^double x1 ^double y1 ^double x2 ^double y2]
  (Bounds. x1 y1 x2 y2 (* 0.5 (- x2 x1)) (* 0.5 (- y2 y1))))

;; state for interactions
(def bounds (atom (make-bounds -2 -2 2 2)))
(def config (atom {}))

(def canvas (make-canvas w h))
(def window (show-window canvas title))

;; Coloring functions
(def coloring-fns {:f1 (fn [nz z] (m/exp (* -6.0 ^double (v/mag nz))))
                   :f2 (fn [nz z] (m/exp (* -6.0 ^double (v/magsq nz))))
                   :f3 (fn [nz z] (m/exp (/ -6.0 ^double (v/mag (v/sub nz z)))))
                   :f4 (fn [nz z] (m/exp (/ -6.0 ^double (v/magsq (v/sub nz z)))))})

;; Fractal definitions
(def iter-fns {:ducks (fn [^Vec2 z c] (c/log (c/add (Vec2. (.x z) (m/abs (.y z))) c)))
               :ducksv1 (fn [^Vec2 z c] (c/log (c/sin (c/add (Vec2. (.x z) (m/abs (.y z))) c))))
               :ducksv2 (fn [^Vec2 z c]
                          (let [nz (c/add (Vec2. (.x z) (m/abs (.y z))) c)]
                            (c/log (v/sub nz (c/sec nz)))))
               :ducksv3 (fn [^Vec2 z c] (c/log (v/add (c/sin (Vec2. (.x z) (m/abs (.y z)))) c)))
               :ducksv4 (fn [^Vec2 z c] (c/log (c/sq (c/add (Vec2. (.x z) (m/abs (.y z))) c))))
               :kali (fn [z c] (v/add (v/div (v/abs z) (v/magsq z)) c))
               :kali2 (fn [z c] (v/add (v/abs (c/reciprocal z)) c))
               :kali3 (fn [z c] (v/add (v/abs (c/reciprocal (c/sq z))) c))
               :kali4 (fn [z c] (v/add (c/sin (v/abs (c/reciprocal z))) c))
               :kali2l (fn [z c] (c/log (v/add (v/abs (c/reciprocal z)) c)))
               :kali3l (fn [z c] (c/log (v/add (v/abs (c/reciprocal (c/sq z))) c)))
               :kali4l (fn [z c] (c/log (v/add (c/sin (v/abs (c/reciprocal z))) c)))
               :kalinewa (fn [z c]
                           (let [nz (v/abs (v/add (c/mult z c) c/ONE))]
                             (v/add nz (c/reciprocal nz))))
               :kalinew (fn [z c]
                          (let [nz (v/add (c/mult z c) c/ONE)]
                            (v/add nz (c/reciprocal nz))))
               :kaliabs (fn [z c] (v/add (v/abs (c/div z c)) c))})

;; Randomize 'c' parameter
(def rand-c {:ducks #(Vec2. (r/drand 0.2 0.95) (r/drand -0.25 -1.5))
             :ducksv1 #(Vec2. (r/drand 0.2 0.95) (r/drand -0.25 -1.5))
             :ducksv2 #(Vec2. (r/drand -0.1 1.2) (r/drand -0.1 -1.5))
             :ducksv3 #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 0.5))
             :ducksv4 #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 0.0))
             :kali #(Vec2. (r/drand -0.1 -1.9) (r/drand -0.1 -1.9))
             :kali2 #(Vec2. (r/drand -0.1 -1.9) (r/drand -1.9 0.0))
             :kali3 #(Vec2. (r/drand -1.2 1.2) (r/drand -1.2 1.2))
             :kali4 #(Vec2. (r/drand -1.5 0.2) (r/drand -1.2 0.2))
             :kali2l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kali3l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kali4l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kalinewa #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 1.5))
             :kalinew #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 1.5))
             :kaliabs #(Vec2. (r/drand -0.8 -0.1) (r/drand -0.8 -0.1))})

(defn draw-ducks
  "Iterate and draw"
  [canvas {:keys [c-const coloring-fn iter-fn ^double mlt]}]
  (let [f (coloring-fns coloring-fn)
        iter (iter-fns iter-fn)
        ^Bounds cbounds @bounds
        factor (max 0.0 (- (m/log2 (.sx cbounds))))
        limit (+ 20.0 (* 3.0 factor))
        ww (+ 7.0 factor)]
    (dotimes [x w]
      (dotimes [y h]
        (let [xx (m/norm x 0.0 w (.x1 cbounds) (.x2 cbounds))
              yy (m/norm y 0.0 h (.y1 cbounds) (.y2 cbounds))
              m (loop [i (int 0)
                       z (Vec2. xx yy)
                       sum (double 0)
                       wsum (double 0)]
                  (let [w (m/exp (- (/ i ww)))
                        nz (iter z c-const)]
                    (if (< i limit)
                      (recur (inc i)
                             nz 
                             (+ sum (* w ^double (f nz z)))
                             (+ wsum w))
                      (/ sum wsum))))
              col (* 255 (m/abs (m/qsin (* mlt m/TWO_PI (m/sqrt m)))))]
          (set-color canvas col col col)
          (rect canvas y x 1 1)))))
  canvas)

(defn draw-fractal
  "Draw fractal"
  []
  (with-canvas canvas
    (draw-ducks @config)
    (p/set-canvas-pixels! (p/filter-channels p/normalize-filter nil (p/get-canvas-pixels canvas))))
  (println "done!"))


(defn new-fractal
  "Create new config and draw fractal"
  []
  (let [cfname (rand-nth (keys coloring-fns))
        itername (rand-nth (keys iter-fns))
        conf {:c-const ((rand-c itername))
              :coloring-fn cfname
              :mlt (r/drand 1 3)
              :iter-fn itername}]
    (pprint conf)
    (reset! config conf)
    (reset! bounds (make-bounds -2 -2 2 2))
    (draw-fractal)))

(defmethod key-pressed [title \n] [_]<commit_msg>added burning ship to ex34<commit_after>;; http://www.algorithmic-worlds.net/blog/blog.php?Post=20110227
;; https://softologyblog.wordpress.com/2011/04/05/ducks-fractals/

;; Interactions, press:
;;
;; * n - new configuration and render
;; * z - zoom in
;; * x - zoom out
;; * SPACE - save image
;;
;; Click mouse to make new center point

(ns examples.ex34-ducks-kalisets
  (:require [clojure2d.core :refer :all]
            [clojure2d.math :as m]
            [clojure2d.math.complex :as c]
            [clojure2d.math.vector :as v]
            [clojure2d.pixels :as p]
            [clojure2d.math.random :as r]
            [clojure.pprint :refer :all])
  (:import [clojure2d.math.vector Vec2 Vec4]))

(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)

(def ^:const ^int w 800)
(def ^:const ^int h 800)

(def ^:const title "Ducks and Kalis")

(deftype Bounds [^double x1 ^double y1
                 ^double x2 ^double y2
                 ^double sx ^double sy]
  Object
  (toString [b] (str "[(" x1 ", " y1 "), (" x2 ", " y2 ")]")))

(defn make-bounds
  ""
  [^double x1 ^double y1 ^double x2 ^double y2]
  (Bounds. x1 y1 x2 y2 (* 0.5 (- x2 x1)) (* 0.5 (- y2 y1))))

;; state for interactions
(def bounds (atom (make-bounds -2 -2 2 2)))
(def config (atom {}))

(def canvas (make-canvas w h))
(def window (show-window canvas title))

;; Coloring functions
(def coloring-fns {:f1 (fn [nz z] (m/exp (* -6.0 ^double (v/mag nz))))
                   :f2 (fn [nz z] (m/exp (* -6.0 ^double (v/magsq nz))))
                   :f3 (fn [nz z] (m/exp (/ -6.0 ^double (v/mag (v/sub nz z)))))
                   :f4 (fn [nz z] (m/exp (/ -6.0 ^double (v/magsq (v/sub nz z)))))})

;; Fractal definitions
(def iter-fns {:ducks (fn [^Vec2 z c] (c/log (c/add (Vec2. (.x z) (m/abs (.y z))) c)))
               :ducksv1 (fn [^Vec2 z c] (c/log (c/sin (c/add (Vec2. (.x z) (m/abs (.y z))) c))))
               :ducksv2 (fn [^Vec2 z c]
                          (let [nz (c/add (Vec2. (.x z) (m/abs (.y z))) c)]
                            (c/log (v/sub nz (c/sec nz)))))
               :ducksv3 (fn [^Vec2 z c] (c/log (v/add (c/sin (Vec2. (.x z) (m/abs (.y z)))) c)))
               :ducksv4 (fn [^Vec2 z c] (c/log (c/sq (c/add (Vec2. (.x z) (m/abs (.y z))) c))))
               :kali (fn [z c] (v/add (v/div (v/abs z) (v/magsq z)) c))
               :kali2 (fn [z c] (v/add (v/abs (c/reciprocal z)) c))
               :kali3 (fn [z c] (v/add (v/abs (c/reciprocal (c/sq z))) c))
               :kali4 (fn [z c] (v/add (c/sin (v/abs (c/reciprocal z))) c))
               :kali2l (fn [z c] (c/log (v/add (v/abs (c/reciprocal z)) c)))
               :kali3l (fn [z c] (c/log (v/add (v/abs (c/reciprocal (c/sq z))) c)))
               :kali4l (fn [z c] (c/log (v/add (c/sinh (v/abs (c/reciprocal z))) c)))
               :kalinewa (fn [z c]
                           (let [nz (v/abs (v/add (c/mult z c) c/ONE))]
                             (v/add nz (c/reciprocal nz))))
               :kalinew (fn [z c]
                          (let [nz (v/add (c/mult z c) c/ONE)]
                            (v/add nz (c/reciprocal nz))))
               :kaliabs (fn [z c] (v/add (v/abs (c/div z c)) c))
               :my (fn [z c] (c/sec (v/abs (v/add z c))))
               :burningship-log (fn [^Vec2 z c] (c/log (v/add (c/sq (v/abs z)) c)))})

;; Randomize 'c' parameter
(def rand-c {:ducks #(Vec2. (r/drand 0.2 0.95) (r/drand -0.25 -1.5))
             :ducksv1 #(Vec2. (r/drand 0.2 0.95) (r/drand -0.25 -1.5))
             :ducksv2 #(Vec2. (r/drand -0.1 1.2) (r/drand -0.1 -1.5))
             :ducksv3 #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 0.5))
             :ducksv4 #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 0.0))
             :kali #(Vec2. (r/drand -0.1 -1.9) (r/drand -0.1 -1.9))
             :kali2 #(Vec2. (r/drand -0.1 -1.9) (r/drand -1.9 0.0))
             :kali3 #(Vec2. (r/drand -1.2 1.2) (r/drand -1.2 1.2))
             :kali4 #(Vec2. (r/drand -1.5 0.2) (r/drand -1.2 0.2))
             :kali2l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kali3l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kali4l #(Vec2. (r/drand -0.5 1.0) (r/drand -1.5 0.1))
             :kalinewa #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 1.5))
             :kalinew #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 1.5))
             :kaliabs #(Vec2. (r/drand -0.8 -0.1) (r/drand -0.8 -0.1))
             :my #(Vec2. (r/drand -1.5 1.5) (r/drand -1.5 0))
             :burningship-log #(Vec2. (r/drand 0.0 1.0) (r/drand -1.0 0.0))})

(defn draw-ducks
  "Iterate and draw"
  [canvas {:keys [c-const coloring-fn iter-fn ^double mlt var]}]
  (let [f (coloring-fns coloring-fn)
        iter (iter-fns iter-fn)
        ^Bounds cbounds @bounds
        factor (max 0.0 (- (m/log2 (.sx cbounds))))
        limit (+ 20.0 (* 3.0 factor))
        ww (+ 7.0 factor)]
    (dotimes [x w]
      (dotimes [y h]
        (let [xx (m/norm x 0.0 w (.x1 cbounds) (.x2 cbounds))
              yy (m/norm y 0.0 h (.y1 cbounds) (.y2 cbounds))
              m (loop [i (int 0)
                       z (Vec2. xx yy)
                       sum (double 0)
                       wsum (double 0)]
                  (let [w (m/exp (- (/ i ww)))
                        nz (iter z c-const)]
                    (if (< i limit)
                      (recur (inc i)
                             nz 
                             (+ sum (* w ^double (f nz z)))
                             (+ wsum w))
                      (/ sum wsum))))
              col (* 255 (m/abs (m/qsin (* mlt m/TWO_PI (m/sqrt m)))))]
          (set-color canvas col col col)
          (rect canvas y x 1 1)))))
  canvas)

(defn draw-fractal
  "Draw fractal"
  []
  (with-canvas canvas
    (draw-ducks @config)
    (p/set-canvas-pixels! (p/filter-channels p/normalize-filter nil (p/get-canvas-pixels canvas))))
  (println "done!"))

(defn new-fractal
  "Create new config and draw fractal"
  []
  (let [cfname (rand-nth (keys coloring-fns))
        itername (rand-nth (keys iter-fns))
        itername :burningship-log
        conf {:c-const ((rand-c itername))
              :coloring-fn cfname
              :mlt (r/drand 1 3)
              :iter-fn itername}]
    (pprint conf)
    (reset! config conf)
    (reset! bounds (make-bounds -2 -2 2 2))
    (draw-fractal)))

(defmethod key-pressed [title \n] [_]
{'fraction_non_alphanumeric': 0.19358487517168943, 'fraction_numerical': 0.04605316312515149, 'mean_word_length': 1.5717847496364015, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5900256', 'n_tokens_mistral': 5367, 'n_tokens_neox': 5067, 'n_words': 1425}