Grammars

Surfaces are grown using a grammar. The grammar tells us how each surface element should be altered during each growth step.

There are three kinds of grammars in GENR8, predefined, user-defined and evolved.

It is recommended that you start by using the predefined grammars until you feel that you have understood the growth model and the environment. It is much easier to figure out the effects of the environment if you have a rough idea of what the outcome will be.

Predefined

Three-sided Tiles

This grammar produces a triangular surfaces that gets subdivided in to smaller and smaller triangles. The grammar is defined as:

   Edge0 + Edge1 + Edge2
   Edge0 -> Edge0 [ [ [ [ + Edge2 ] + + Edge1 ] - Edge1 ] - - Edge2 ] Edge0
   Edge1 -> Edge1 [ [ [ [ + Edge0 ] + + Edge2 ] - Edge2 ] - - Edge0 ] Edge1
   Edge2 -> Edge2 [ [ [ [ + Edge1 ] + + Edge0 ] - Edge0 ] - - Edge1 ] Edge2
   Angle 60
   Sync

Four-sided Tiles

This grammar produces a square surface which is subdivided in to smaller squares. The grammar is:

   Edge0 + ~ Edge1 + ~ Edge0 + Edge1
   Edge0 -> Edge0 [ [ + Edge1 ] - Edge1 ] Edge0
   Edge1 -> Edge1 [ [ + Edge0 ] - Edge0 ] Edge1
   Angle 90

Koch curve

The Koch curve is an example of a fractal and it is a curve rather than a surface and it is not of much use for generating surfaces. However, fractals are interesting in themselves and the ability to generate them comes "for free" with the growth model. The grammar is:

   Edge0 + Edge0 + Edge0
   Edge0 -> Edge0 - Edge0 + + Edge0 - Edge0
   Angle 60

Quadratic Koch curve

The quadratic Koch curve is a variant of the Koch curve.

   Edge0 + Edge0 + Edge0 + Edge0
   Edge0 -> Edge0 + Edge0 - Edge0 - Edge0 Edge0 + Edge0 + Edge0 - Edge0
   Angle 90

User-defined

GENR8 can parse grammars that are defined by the user. The grammars used by GENR8 are expressed on Backus-Naur Form (BNF).The parser can handle all grammars that are generated from the following definition.

N = { RewriteRule, Predecessor, Successor, Modifier, Operator, Axiom, Condition, LSystem, Segment }

T = { +, -, &, ^, \, /, ~, [, ], <, >, Edge, -> }

S = { <LSystem> }

P = {

<LSystem>	::=	<Axiom> <RewriteRule> { <RewriteRule> }

<Axiom>		::=	<Segment> [ "~" ] "+" <Segment> [ "~" ] "+" <Segment> { [ "~" ] "+" <Segment> }

<RewriteRule>	::=	<Predecessor> "->" <Successor> [ <Condition>]

<Predecessor>	::=	<Segment> |
			<Segment> "<" <Segment> |
			<Segment> ">" <Segment> |
			<Segment> "<" <Segment> ">" <Segment>

<Successor>	::=	{ <Modifier> } <Segment>

<Condition>	::=	"If"

<Modifier>	::=	{ <Segment> } |
			"+" <Modifier> "-" |
			"-" <Modifier> "+" |
			"&" <Modifier> "^" |
			"^" <Modifier> "&" |
			"\" <Modifier> "/" |
			"/" <Modifier> "\" |
			"~" <Modifer> |
			"[" "[" "+" { <Operator> } <Segment> "]" "-" { <Operator> } <Segment> "]"

<Operator>	::=	"+"	|
			"-"	|
			"&"	|
			"^"	|
			"\"	|
			"/"	|
			"~"	|

Most of this information is unnecessary when writing your own grammar. Instructions for creating a grammar file can be found here.

Evolved

There are obviously an infinite set of possible grammars and in order to be able to search them somewhat more effectively, there is an evolutionary component that does this. When generating grammars the evolutionary algorithm uses a BNF that is very similar to the one described above. You can use one of the following.

Default

The default BNF has been specified to generate a lot of branches. This will in turn produce subdivisions, which in general is a desired property for a surface.

Reversible

This BNF produces grammars that can be inverted using regn8.

Symmetric

The symmetric BNF creates a grammar that produces a symmetric surface.

Probabilistic

This BNF produces grammars with probabilistic productions.