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.
As successfully as to the 2nd/3d vectors supplied via
cl-veq, the principal parts are:
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
(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.
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.
A tool for drawing
wsvg. Glimpse design.articulate.
Weir Graphs and Alterations
The most gripping phase of the
weir graph structure is
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
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
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))) (veq:f3+ xy (veq:f3< 1.0 2.0 (rnd:rnd))))) :g g?)))))))
I even admire written about issues associated to this code at:
- https://inconvergent.accumulate/2017/snek-is-no longer-an-acronym/
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
#+quicklisp (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
Additionally, many thanks to https://twitter.com/xach for making Quicklisp.