Uncommon: Generative Art in Classic Suppose

Uncommon: Generative Art in Classic Suppose

NOTE: it’s main to never exhaust this code for anything remotely vital


queer is the following iteration of weir
which used to be the following iteration of snek.
The library is written to be vital for an amazing vary of ways wherein I invent
artwork the exhaust of generative algorithms. Virtually all the pieces I even admire made over the
previous several years has been made the exhaust of some model of this methodology.

Elastic Web


As successfully as to the 2nd/3d vectors supplied via
cl-veq, the principal parts are:

  1. A easy (undirected) graph records structure, weir. The structure will also be
    manipulated straight, or via alterations. The latter is described in more
    detail below. Here’s a easy instance of guidelines on how to manipulate the
    structure straight:

    (in-equipment :weir)
    (let ((wer (influence)))
      ; add three edges
      (loop repeat 3
            carry out (add-edge! wer
                 (2add-vert! wer
                   (rnd:2in-circ 200.0))
                 (2add-vert! wer
                   (veq:f2+ (veq:2rep 500.0)
                            (rnd:2in-circ 200.0))))
      ; iterate verts
      (itr-verts (wer v)
        ; prints vert coordinates
        (veq:vpr (2get-vert wer v)))
      ; iterate edges
      (itr-edges (wer vv)
        (veq:vpr (2get-verts wer vv)))
      ; go a vert relativ to contemporary space: 
      (2move-vert! wer 0 1.0 2.0)
      ; or to an absolute space
      (2move-vert! wer 1 1.0 2.0 :rel nil)
      ; edges are represented as lists of verts, and they're continuously
      ; sorted with the smallest vert index first, so each of these
      ; return t: 
      (edge-exists wer '(0 1))
      (edge-exists wer '(1 0))
      ; accumulate edges incident to vert 0
      (accumulate-incident-edges wer 0))

    Glimpse examples/design.articulate and
    examples/design.articulate for more.

  2. Random numbers, some examples:

    (in-equipment :rnd)
    (rnd a) ; in vary [0.0, a), defaults to a=1.0.
    (rnda) ; in vary [-a, a), defaults to a=1.0.
    (rndrng a b) ; in vary [a, b)
    (rndi 10) ; random fixnum
    (rndspace n a b) ; n numbers in [a, b)
    (norm :mu 0.0 :sigma 1.0) ; usual distribution
    (2in-circ a) ; in circle of radius a
    (2in-rect w h) ; in a rectangle
    (2nin-rect n w h) ; n in rectangle.
    (2on-line ax ay bx by) ; level between aspects a and b
    ; carry out something with likelihood 0.1, 2nd accept as true with is optional
    (prob 0.1 (print "10% hi") (print "90% oh no"))
    ; invent either accept as true with 1 or (optionally) 2
    (either (print "accept as true with 1") (print "accept as true with 2"))

    Glimpse rnd.articulate, 2rnd.articulate and
    3rnd.articulate, for all on hand functions.

  3. A tool for drawing svg recordsdata: wsvg. Glimpse design.articulate.


Weir Graphs and Alterations

The most gripping phase of the weir graph structure is alterations. An
alteration is a alternate that will doubtless be applied to the structure at the pause of a
given context, supplied it’s a long way legit.

The most vital motivation behid right here is that this makes it doable to “queue” up a
preference of changes that will doubtless be applied at a later time. This makes it doable
to accumulate admission to the say within the weir event whereas you’re setting up the
alterations. Without there being any changes made to the say of the weir
event whereas the alterations are being created. As soon as all alterations are
created, the legit ones will doubtless be applied.

Existing alterations in weir are postfixed with ?. it’s a long way going to hunt love this:

(weir:with (wer %)
  (% (add-vert? (veq:f2< 100.0 740.0))
  (% (add-edge? 1 4)))

(% ...) is outmoded to amass alterations. They’ll be performed at the pause of
the with context. If an alteration evaluates to nil, nothing will happen.

Here is an instance of how the forces are calcualted in my Tangle of Webs

(veq:vdefreciprocal-edge-forces (wer &key (stp 0.1))
  (weir:with (wer %)
    ; say of wer is unaltered
    (weir:itr-edges (wer e) ; edge (v0 v1)
      ; vector from v0 to v1
      ; pressure is proportional to this "oriented distance"
      (veq:f2let ((pressure (veq:f2-
                           (veq:f2$ (weir:2get-verts wer e)
                                    1 0))))
        (loop for i in e and s in '(-1.0 1.0)
              ; alteration is created, but nothing happens
              carry out (% (weir:2move-vert? i
                      (veq:f2scale pressure s stp)))))))))
    ; alterations are applied at the pause
    ; of the context

The vital ingredient to illustrate right here is that for the forces to be calculated
properly, all edge lengths ought to be calculated earlier than the forces are applied
to the vertices.


Futures and Dependencies

That it’s probably you’ll effect a title to the of an alteration the exhaust of

(% (add-edge? 1 3) :res :some-title?)

This makes it doable to invent alterations that rely upon the of totally different

(in-equipment :weir)
(with (wer %)
  (veq:f2let ((pt (veq:f2< 1f0 3f0)))
    (% (2add-vert? pt) :res :a?) ; alteration result is known as :a?
    (% (2add-vert? (veq:f2< 1.0 2.0)) :res :b?) ; result named :b?
    (% (add-edge? :a? :b?)))) ; depends on :a? and :b?

; all alteration results: 
(print (accumulate-alteration-result-record wer))
; or as a `hash-scheme`: 
(print (accumulate-alteration-result-scheme wer))

alteration names ought to be keywords that pause with ?. (There is an
exception, gawk Looping below.) And the exhaust of the an identical title for more than one
alterations will lead to undefined behaviour.

As it’s probably you’ll maybe well well perchance gawk, a named alteration is an associated to a future; a reference to a
result that will or might well well well also unbiased no longer exist sooner or later. For this to work, any alteration
that depends on a future that fails (or returns nil) will doubtless be skipped.

That it’s probably you’ll exhaust (weir:with (wer % :bd t) ...) to hunt how an alteration is
expanded. This is in a position to maybe well influence it more straightforward to hunt what’s going on.



It is a long way feasible to make exhaust of alterations inside of loops as successfully. on the opposite hand it requires reasonably
more careful consideration. Here is an instance:

(in-equipment :weir)
(with (wer % :db t)
  (loop for x in (math:linspace 20 -20.0 20.0) carry out
    (loop for z in (record 1.0 2.0) carry out
      (veq:f3let ((xy (veq:f3< x y z)))
        ; invent a decided title
        (let ((g? (gensym "g")))
          (% (add-grp? :title (gensym "line")) :res g?)
          (% (2add-course?
               (veq:f$_ (record (veq:f3-
                                xy (veq:f3< 1.0 8.0 (rnd:rnd)))
                                xy (veq:f3< 1.0 2.0 (rnd:rnd)))))
               :g g?)))))))


I even admire written about issues associated to this code at:

Mark that these posts consult with older iterations of the code. So one of the crucial
issues will doubtless be old-usual.


On Expend and Contributions

This code is written for my inside of most exhaust, and parts of it’s a long way extremely
experimental. Additionally, it’s a long way at possibility of alternate at my whim. That’s the reason I don’t
point out reckoning on this library for anything.

I free up it publicly in case of us procure it vital or gripping. It is a long way no longer,
on the opposite hand, intended as a collaboration/Begin Offer mission. As such I am no longer going
to accept PRs, acknowledge to issues, or acquire requests.

Installation and Dependencies

queer depends on cl-veq, and
it requires Quicklisp to install dependencies (that are listed in

To install and cargo queer, carry out:

If this does no longer work, queer might well well well also unbiased no longer be in a local Quicklisp or ASDF can gawk
them. To repair this, either:

For a actually long length of time resolution, add the following to .sbclrc:

(push "/course/to/dir/containing/queer" ql: *local-mission-directories*)

You’ve to be obvious cl-veq is also on hand within the an identical trend for
any of this to work.


Assessments will also be performed the exhaust of: (asdf:take a look at-map :queer).


I’d love to thank:

Who admire supplied me with vital hints and code feedback.

The ASDF config and take a look at setup used to be tremendous instructed and implemented by Robert
Smith (https://twitter.com/stylewarning). Even when I even admire made some changes
since then.

Additionally, many thanks to https://twitter.com/xach for making Quicklisp.



Hey! look, i give tutorials to all my users and i help them!

you're currently offline