--- a/flax.asd Wed Mar 14 22:52:58 2018 -0400
+++ b/flax.asd Thu Mar 15 00:28:01 2018 -0400
@@ -39,5 +39,6 @@
(:file "002-wobbly-lines")
(:file "003-basic-l-systems")
(:file "004-turtle-curves")
- (:file "005-simple-triangulations")))))))
+ (:file "005-simple-triangulations")
+ (:file "006-tracing-lines")))))))
--- a/package.lisp Wed Mar 14 22:52:58 2018 -0400
+++ b/package.lisp Thu Mar 15 00:28:01 2018 -0400
@@ -1,6 +1,6 @@
(defpackage :flax.base
(:use :cl :iterate :losh :flax.quickutils)
- (:export :rand :with-seed))
+ (:export :rand :with-seed :round-to))
(defpackage :flax.coordinates
(:use :cl :iterate :losh :flax.base :flax.quickutils)
@@ -62,4 +62,10 @@
:flax.coordinates)
(:export :loom))
+(defpackage :flax.looms.006-tracing-lines
+ (:use :cl :iterate :losh :flax.base :flax.quickutils
+ :flax.colors
+ :flax.coordinates)
+ (:export :loom))
+
--- a/src/base.lisp Wed Mar 14 22:52:58 2018 -0400
+++ b/src/base.lisp Thu Mar 15 00:28:01 2018 -0400
@@ -4,5 +4,20 @@
(pcg:pcg-random t bound))
(defmacro with-seed (seed &body body)
- `(let ((pcg::*global-generator* (pcg:make-pcg :seed ,seed))) ,@body))
+ `(let ((pcg::*global-generator* (pcg:make-pcg :seed ,seed)))
+ (losh::clear-gaussian-spare)
+ ,@body))
+
+
+(defun round-to (number precision)
+ "Round `number` to the given `precision`.
+ Examples:
+
+ (round-to 13 10) ; => 10
+ (round-to 15 10) ; => 20
+ (round-to 44 25) ; => 50
+ (round-to 457/87 1/2) ; => 11/2
+
+ "
+ (* precision (round number precision)))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/looms/006-tracing-lines.lisp Thu Mar 15 00:28:01 2018 -0400
@@ -0,0 +1,67 @@
+(in-package :flax.looms.006-tracing-lines)
+
+;;;; Config -------------------------------------------------------------------
+(defparameter *spread* 0.0020)
+
+
+;;;; Convert ------------------------------------------------------------------
+(defun convert-point (point x y)
+ (coord x (+ y point)))
+
+(defun convert-line (line y)
+ (flax.drawing:path
+ (iterate (for point :in-vector line)
+ (for x :from 0.0 :by (/ (1- (length line))))
+ (collect (convert-point point x y)))
+ :color (hsv 0 0 1)))
+
+(defun convert-lines (lines)
+ (iterate (for line :in lines)
+ (for y :from 0.0 :by (/ (length lines)))
+ (collect (convert-line line y))))
+
+
+;;;; Generate -----------------------------------------------------------------
+(defun make-initial-line (points)
+ (make-array points :initial-element 0.0))
+
+(defun perturb (point)
+ (random-around point *spread* #'rand))
+
+(defun wrapping-aref (array i)
+ (aref array (mod i (length array))))
+
+(defun average (sequence)
+ (iterate (for x :in-whatever sequence)
+ (averaging x)))
+
+(defun next-line (line)
+ (iterate (for i :index-of-vector line)
+ (collect (random-gaussian
+ (average (subseq line
+ (max 0 (- i 2))
+ (min (1- (length line)) (+ i 1))))
+ *spread* #'rand)
+ :result-type 'vector)))
+
+(defun generate-lines (points lines)
+ (iterate
+ (repeat lines)
+ (for line :first (make-initial-line points) :then (next-line line))
+ (collect line)))
+
+
+;;;; Main ---------------------------------------------------------------------
+(defun loom (seed filename filetype width height)
+ (nest
+ (with-seed seed)
+ (flax.drawing:with-rendering (canvas filetype filename width height
+ :background (hsv 0 0 0.05)))
+ (let* ((points (round-to (random-range 100 150 #'rand) 10))
+ (lines (round-to (random-range 80 140 #'rand) 10))
+ (*spread* (/ 0.15 lines))))
+ (progn
+ (flax.drawing:render canvas (convert-lines (generate-lines points lines)))
+ (list points lines))))
+
+;; (time (loom nil "out" :svg 800 800))