aboutsummaryrefslogtreecommitdiffstats
path: root/lib/gs/examples/frac.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gs/examples/frac.erl')
-rw-r--r--lib/gs/examples/frac.erl154
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/gs/examples/frac.erl b/lib/gs/examples/frac.erl
new file mode 100644
index 0000000000..139a4be310
--- /dev/null
+++ b/lib/gs/examples/frac.erl
@@ -0,0 +1,154 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%% Purpose : Fractal trees
+
+-module(frac).
+
+-export([start/0, go/0, test/0, grow/2, expand/3, subst/2]).
+
+%% 0L - grammer -- context insensitive lindenmayer grammer
+
+start() ->
+ spawn(frac,go,[]).
+
+go() ->
+ draw(),
+ receive
+ _X -> true
+ end.
+
+draw() ->
+ S=gs:start(),
+ Width = 800,
+ Ht = 520,
+ Title="Context Insensitive Lindenmayer Grammer (L0) Trees",
+ Win=gs:create(window,S,[{title,Title},{width,Width},{height,Ht}]),
+ Canvas=gs:create(canvas,Win,[{width,Width},{height,Ht},{bg,{237,224,189}}]),
+ gs:config(Win,[{iconname,"Plants"},{map,true}]),
+ draw(Canvas, 1, Width, Ht),
+ draw(Canvas, 2, Width, Ht),
+ draw(Canvas, 3, Width, Ht),
+ draw(Canvas, 4, Width, Ht).
+
+draw(Graph, Index, Width, Ht) ->
+ draw_frac(Graph, Index, Width, Ht).
+
+test() ->
+ grow(3,1).
+
+grow(NGens, RuleNumber) ->
+ lists:flatten(expand(NGens, RuleNumber, [a])).
+
+rule(1,a) -> [b,'[',a,']',b,'(',a,')',a];
+rule(1,b) -> [b,b];
+
+rule(2,a) -> [b,'[',a,'[',b,a,']',']'];
+rule(2,b) -> [b,'(','(',b,')',a,')',c];
+rule(2,c) -> [c,d];
+
+rule(3,a) -> [d,'[',d,b,e,']','(',d,c,e,')'];
+rule(3,b) -> [d,'[',d,a,f,']','(',d,c,f,')',f];
+rule(3,c) -> [d,'[',d,b,g,']','(',d,a,g,')',g];
+
+rule(4,a) -> [c,'(',b,a,'(',b,')',')',c,'[',b,a,'[',b,']',']'];
+rule(4,b) -> [c,'(',b,e,')',c,'[',b,f,']'];
+rule(4,c) -> [g,c,c];
+
+rule(_,X) -> X.
+
+
+step(a) -> 1.0;
+step(b) -> 0.8;
+step(c) -> 0.6;
+step(d) -> 0.7;
+step(e) -> 0.6;
+step(f) -> 0.65;
+step(g) -> 0.75;
+step(_) -> 1.0.
+
+start_coords(1) -> {0.8,0.8};
+start_coords(2) -> {0.6,0.8};
+start_coords(3) -> {0.4,0.8};
+start_coords(4) -> {0.2,0.8};
+start_coords(_) -> {0.5, 0.5}.
+
+gens(1) -> 5;
+gens(_) -> 5.
+
+scale(1) -> 5;
+scale(2) -> 40;
+scale(3) -> 40;
+scale(4) -> 4;
+scale(_) -> 5.
+
+expand(0,_,X) ->
+ X;
+expand(N,Index,X) ->
+ expand(N - 1, Index, lists:flatten(subst(X, Index))).
+
+
+subst([],_) -> [];
+subst([H|T],Index) ->
+ [rule(Index,H)|subst(T,Index)].
+
+
+draw_frac(Id, Index, Width, Ht) ->
+ X0 = 100,
+ Y0 = 100,
+ {XScale,YScale} = start_coords(Index),
+ Xstart = trunc(X0 + Width*XScale),
+ Ystart = trunc(Y0 + Ht*YScale),
+ Angle = 270.0 * 3.14159 / 180.0,
+ Scale = scale(Index),
+ N = gens(Index),
+ Tree = grow(N,Index),
+ drawit(Tree, Id, Xstart, Ystart, Angle, Scale, []).
+
+% drawit(Tree,S0,S).
+
+drawit([],_,_,_,_,_,_) ->
+ true;
+drawit(['('|T],Id,X0,Y0,Ang,Scale,Stack) ->
+ Ang1 = Ang + (20.0 * 3.14159 / 180.0),
+ Scale1 = Scale * 0.8,
+ drawit(T,Id,X0,Y0,Ang1,Scale1,[{X0,Y0,Ang,Scale}|Stack]);
+drawit(['['|T],Id,X0,Y0,Ang,Scale,Stack) ->
+ Ang1 = Ang - (40.0 * 3.14159 / 180.0),
+ Scale1 = Scale * 0.8,
+ drawit(T,Id,X0,Y0,Ang1,Scale1,[{X0,Y0,Ang,Scale}|Stack]);
+drawit([')'|T],Id,_,_,_,_,[{X1,Y1,Ang1,Scale1}|Stack]) ->
+ drawit(T,Id,X1,Y1,Ang1,Scale1,Stack);
+drawit([']'|T],Id,_,_,_,_,[{X1,Y1,Ang1,Scale1}|Stack]) ->
+ drawit(T,Id,X1,Y1,Ang1,Scale1,Stack);
+drawit([Symbol|T],Id,X0,Y0,Ang,Scale,Stack) ->
+ Size = step(Symbol),
+ L = Size * Scale,
+ {X1, Y1} = plotit(Id,X0,Y0,L,Ang),
+ drawit(T,Id,X1,Y1,Ang,Scale,Stack).
+
+plotit(Id,X0,Y0,L,A) ->
+ CosA = math:cos(A),
+ SinA = math:sin(A),
+ X = trunc(X0 + L*CosA),
+ Y = trunc(Y0 + L*SinA),
+ gs:create(line,Id,[{coords,[{X0,Y0},{X,Y}]}]),
+ {X,Y}.
+