cl-aristid: Draw Lindenmayer Systems with Common LISP

栏目: IT技术 · 发布时间: 4年前

内容简介:Draw Lindenmayer Systems with Common LISP!A Lindenmayer system (L-system) is a model originally designed by Aristid Lindenmayer in the 60s to describe plant growth. Another common use for this system is as a technique to generate fractals, i.e, a self-simi

cl-aristid

Draw Lindenmayer Systems with Common LISP!

1.Introduction

A Lindenmayer system (L-system) is a model originally designed by Aristid Lindenmayer in the 60s to describe plant growth. Another common use for this system is as a technique to generate fractals, i.e, a self-similar geometric figure.

The main idea of this model is to start with a string of symbols such as "F G", and then, rewrite that original string N times, according to some rules such as "replace every F with 'F G F'" and "replace every G with 'G G F'". After doing this rewrite, we have a final string of symbols, and if we define some of those symbols to have some drawing action attached, such as 'F means draw a line forward' and 'G means draw a line to the right', we will end up with a drawing of our fractal.

An L-system requires 3 things to be defined:

  • The alphabet: symbols which may be replaced in our string, and which may have some drawing action attached to it. In this program, we call each of this symbols an 'aristid' (this is because the original definition of the L-system differentiates between variable symbols and constant symbols, but there is no practical difference between them, so we need a term to group them together (and symbol is kind of taken by the LISP community))

  • The axiom: the original string we will start rewriting

  • The rules: the production rewrite rules which tells which symbols replace by which on each iteration

The main idea of this programis to define each of this things that the system requires, and then draw it, exporting it to a .svg

2.Example

Go to the examples folder to look at the code for several fractals and see them in action by running make !

Drawing the Dragon Curve with cl-aristid

  1. First, we want to enter SBCL (just write sbcl in the terminal, inside the root of the repository) and load this package
(ql:update-dist "quicklisp")
(ql:quickload "cl-aristid")
  1. After the call to use-package we now have access to the symbols exposed by the package, detailed in.
(use-package 'cl-aristid)
  1. defaristid

We now want to define the different aristids of our fractal. We are calling an 'aristid' to each symbol on our Lindenmayer alphabet that does something , that is, to any drawing function. If we check the Dragon Curve definition , we have 3 aristids (F, + and -). As LISP already has defined the + and - symbols, we will replace them with RIGHT and LEFT

(defaristid F :len 2) ; The letter F draws forward a line of length 2.
(defaristid LEFT :angle 90) ; LEFT will turn left 90 degrees
(defaristid RIGHT :angle -90) ; RIGHT will turn right 90 degrees
  1. defrule

After our aristids, we want to define the production rules. This rules are the ones that will rewrite our function string on each iteration. The Dragon Curve has only 2 rules: (X → X + Y F +) and (Y → − F X − Y) . This means that on each iteration we will replace X with X + Y F + and the same happens to Y .

; We wrap every rule in a LISP list, to use as an argument later
(defparameter dragon-rules
	(list (defrule X -> (X RIGHT Y F RIGHT))
		  (defrule Y -> (LEFT F X LEFT Y))))
  1. make-fractal

We have almost everything to define our fractal! Remember, a L-system consists of three things: the alphabet of symbols (our aristids), the production rules, and an axiom, which is the first string to be rewritten. In the Dragon Curve example, the axiom is (F X)

We want to call make-fractal with all of this attributes.

(defparameter dragon (make-fractal :name "dragon"
								   :rules dragon-rules
								   :axiom '(F X)))
  1. draw

We are now ready to draw! We just call the draw function that receives our fractal and the N iterations we want

(draw dragon 10)
  1. Result

cl-aristid: Draw Lindenmayer Systems with Common LISP

  1. Let's pass it through vivus for one last look

cl-aristid: Draw Lindenmayer Systems with Common LISP

3.Interface

defrule symbol -> (newsymbol newsymbol2) :prob 1.00

The macro defrule is used to create a new production rule to rewrite the string.

It recives the symbol to be rewritten, then an -> to symbolize the L-system rule, and then a list of the new symbols to be used. It can also receive a prob argument, which is explained inand it can also use brackets symbols, which are explained in.

defaristid symbol :angle 0 :len 0 :nodraw nil :color "black"

The macro defaristid is used to create a new aristid.

It receives the name of the symbol we are defining, and a pack of optional arguments which serve as the drawing actions. angle means the change of direction in the current drawing, len means how many dots will be drawn forward (i.e, the length of the line), nodraw can be set to true to only move the direction without actually drawing, and color can be set to any of the 140 HTML color names or even a hex value.

  • if both angle and len are specified, the drawing will first draw forward, and then change the angle
make-fractal :name name :axiom axiom :rules rules

The function make-fractal serves as the constructor for the fractal structure. It receives a name as a string, an axiom which is a list of symbols and the rules which is a list of rules

draw fractal gen

The function draw takes a fractal structure and draws it's gen iteration, saving it in a .svg named fractalname_gen.svg .

4.Cool stuff

Brackets

The bracket symbols ( [ and ] ) are symbols defined by Lindenmayer to save and restore the current direction of the l-system, so that when enclosing a list of symbols between brackets, a new "branch" starts to be drawn. One fractal plant has one of its rules as "(X → F+[[X]-X]-F[-FX]+X)". This can be achieved in cl-aristid with (defrule X -> (F RIGHT [ [ X ] LEFT X ] LEFT F [ LEFT F X ] RIGHT X))

Stochastic L-systems

cl-aristid supports stochastic L-systems, which are systems where rules can be chosen with a certain probability on each iteration of the rewrite. So for example, you want to draw a fractal in which one of it's symbols gets replaced by a list of new symbols only a third of the times it is called, you can define that rule with :prob such as (defrule A -> (A RIGHT B F RIGHT) :prob 0.33)

The aristids you define have a color argument which can be set to any of the 140 HTML color names or hex value. For example (defaristid A :len 8 :color "purple")

Everything together

So I hear you want a fractal plant which has some branches in white and some in salmon? Hold my parenthesis!

(defaristid F :len 4 :color "white")
(defaristid G :len 4 :color "salmon")
(defaristid LEFT :angle 25)
(defaristid RIGHT :angle -25)

(defparameter freaky-fractal-rules
	(list (defrule F -> (F G) :prob 0.45)
		  (defrule G -> (F F) )
		  (defrule X -> (F RIGHT [ [ X ] LEFT X ] LEFT F [ LEFT F X ] RIGHT X))))

(defparameter axiom '(LEFT LEFT LEFT LEFT LEFT LEFT LEFT LEFT X))

(defparameter fractal (make-fractal :name "freaky-fractal-plant"
										:rules freaky-fractal-rules
										:axiom axiom))

(draw tree-fractal 6)

Rainbows

Add :color "rainbow" to your aristid to give it more groove

(defaristid F :len 2 :color "rainbow")
(defaristid LEFT :angle 90)
(defaristid RIGHT :angle -90)

(defparameter rule-1 (defrule X -> (X F X LEFT Y F LEFT Y F RIGHT F X RIGHT F X LEFT Y F LEFT Y F F X RIGHT Y F RIGHT F X F X Y F LEFT F X RIGHT Y F RIGHT F X F X RIGHT Y F LEFT F X Y F LEFT Y F LEFT F X RIGHT F X RIGHT Y F Y F LEFT)))
(defparameter rule-2 (defrule Y -> (RIGHT F X F X LEFT Y F LEFT Y F RIGHT F X RIGHT F X Y F RIGHT F X LEFT Y F Y F LEFT F X LEFT Y F RIGHT F X Y F Y F LEFT F X LEFT Y F F X RIGHT F X RIGHT Y F LEFT Y F LEFT F X RIGHT F X RIGHT Y F Y)))

(defparameter axiom '(LEFT Y F))

(defparameter fractal (make-fractal :name "freaky-quadratic"
										:rules (list rule-1 rule-2)
										:axiom axiom))

(draw fractal 3)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机是怎样跑起来的

计算机是怎样跑起来的

[日] 矢泽久雄 / 胡屹 / 人民邮电出版社 / 2015-5 / 39.00元

本书倡导在计算机迅速发展、技术不断革新的今天,回归到计算机的基础知识上。通过探究计算机的本质,提升工程师对计算机的兴趣,在面对复杂的最新技术时,能够迅速掌握其要点并灵活运用。 本书以图配文,以计算机的三大原则为开端、相继介绍了计算机的结构、手工汇编、程序流程、算法、数据结构、面向对象编程、数据库、TCP/IP 网络、数据加密、XML、计算机系统开发以及SE 的相关知识。 图文并茂,通俗......一起来看看 《计算机是怎样跑起来的》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换