ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/lsys/interp.cpp
Revision: 1.1
Committed: Thu Nov 6 14:31:24 2008 UTC (15 years, 6 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /*
2     * l-system interpreters
3     */
4    
5     #include "config.h"
6    
7     #include "lsys.h"
8     #include "interp.h"
9     #include "interface.h"
10     #include "attr.h"
11    
12     #include <cstdlib>
13     #include <cmath>
14     #include <iostream>
15    
16     #ifndef M_PI
17     # define M_PI 3.14159265358979323846 /* pi */
18     #endif
19    
20     bool interpreter::execute_child (const module &m, const lsys &l) t_err
21     {
22     hash_map<string, lsys *>::const_iterator i;
23     const lsys *sys = &l;
24    
25     do {
26     if ((i = sys->sub_lsys.find (m.str)) != sys->sub_lsys.end ())
27     {
28     module_vec v = m.wrap ();
29    
30     if (i->second->eval (v))
31     {
32     execute (v, *i->second);
33     return true;
34     }
35    
36     break;
37     }
38    
39     sys = sys->parent;
40     } while (sys);
41    
42     return false;
43     }
44    
45     void simple_interpreter::execute(const module_vec &v, const lsys &l) t_err
46     {
47     depth--;
48    
49     string s;
50     module m;
51    
52     for (module_pos i = v.begin (); i != v.end(); ++i)
53     if (!depth || !execute_child (*i, l))
54     cout << *i << " ";
55    
56     depth++;
57     }
58    
59     void simple_interpreter::operator ()(const module_vec &v, const lsys &l) t_err
60     {
61     if (maxdepth > 0)
62     {
63     depth = maxdepth + 1;
64     execute (v, l);
65     cout << endl;
66     }
67     }
68    
69     #define MK(m) point((m), cur.pos, cur.dir[2], cur.attr)
70    
71     turtle_interpreter::turtle_interpreter (gfx_int &interface, bool flat_world) t_no
72     : iface (interface), flat(flat_world)
73     {
74     }
75    
76     void turtle_interpreter::rotate_tl (double phi) t_no
77     {
78     phi *= M_PI/180;
79     double s = sin (phi),
80     c = cos (phi);
81     cur.dir = mat ( vec ( c, s, 0),
82     vec (-s, c, 0),
83     vec ( 0, 0, 1)) * cur.dir;
84     }
85    
86     void turtle_interpreter::rotate_pd (double phi) t_no
87     {
88     if (flat) return;
89    
90     phi *= M_PI/180;
91     double s = sin (phi),
92     c = cos (phi);
93     cur.dir = mat ( vec ( c, 0,-s),
94     vec ( 0, 1, 0),
95     vec ( s, 0, c)) * cur.dir;
96     }
97    
98     void turtle_interpreter::rotate_rl (double phi) t_no
99     {
100     if (flat) return;
101    
102     phi *= M_PI/180;
103     double s = sin (phi),
104     c = cos (phi);
105     cur.dir = mat ( vec ( 1, 0, 0),
106     vec ( 0, c, s),
107     vec ( 0,-s, c)) * cur.dir;
108     }
109    
110     void turtle_interpreter::forward (double d) t_no
111     {
112     cur.pos = cur.pos + d * cur.dir[0];
113     }
114    
115     void turtle_interpreter::attrs_changed () t_err
116     {
117     delta = cur.attr("delta", 45);
118     distance = cur.attr("distance", 10);
119     }
120    
121     void turtle_interpreter::execute (const module_vec &v, const lsys &l) t_err
122     {
123     // cout << "interp " << v << endl;
124     string s;
125     double d;
126     module m;
127     const module_vec damnit;
128    
129     for (module_pos i = v.begin (); i != v.end (); ++i)
130     {
131     // cout << delta << "|" << distance << "> " << cur.pos << " " << cur.dir << " " << i->str << endl;
132     if (i->is_func ("["))
133     {
134     state_stack.push (cur);
135     }
136     else if (i->is_func ("]"))
137     {
138     cur = state_stack.top (), state_stack.pop ();
139     attrs_changed ();
140     }
141     else if (i->is_func ("attr", s, m))
142     {
143     if (m.is_expr)
144     m = module (eval_expr (m, cur.attr));
145    
146     cur.attr[s] = m;
147     attrs_changed ();
148     }
149     else if (i->is_func ("+"))
150     rotate_tl (delta);
151     else if (i->is_func ("-"))
152     rotate_tl (-delta);
153     else if (i->is_func ("+", d))
154     rotate_tl (d);
155     else if (i->is_func ("-", d))
156     rotate_tl (-d);
157     else if (i->is_func ("&"))
158     rotate_pd (delta);
159     else if (i->is_func ("^"))
160     rotate_pd (-delta);
161     else if (i->is_func ("&", d))
162     rotate_pd (d);
163     else if (i->is_func ("^", d))
164     rotate_pd (-d);
165     else if (i->is_func ("\\"))
166     rotate_rl (delta);
167     else if (i->is_func ("/"))
168     rotate_rl (-delta);
169     else if (i->is_func ("\\", d))
170     rotate_rl (d);
171     else if (i->is_func ("/", d))
172     rotate_rl (-d);
173     else if (i->is_func ("|"))
174     rotate_tl (180);
175     else if (i->is_func ("f"))
176     forward (distance);
177     else if (i->is_func ("f", d))
178     forward (d);
179     else if (i->is_func ("F"))
180     {
181     if (obj_stack.empty ())
182     {
183     point o(MK(damnit)); forward (distance); iface.segment (o, MK(damnit));
184     }
185     else
186     {
187     forward (distance); cur_obj.push_back (MK(damnit));
188     }
189     }
190     else if (i->is_func ("F", d))
191     {
192     if (obj_stack.empty ())
193     {
194     point o(MK(damnit)); forward (d); iface.segment (o, MK(damnit));
195     }
196     else
197     {
198     forward (d); cur_obj.push_back (MK(damnit));
199     }
200     }
201     else if (i->is_func ("."))
202     cur_obj.push_back (MK(*i));
203     else if (i->is_func ("{"))
204     {
205     obj_stack.push (cur_obj);
206     cur_obj.erase (cur_obj.begin (), cur_obj.end ());
207     }
208     else if (i->is_func ("}"))
209     {
210     iface.object (cur_obj);
211     if (obj_stack.empty ())
212     throw error ("polygon stack underflow", *i);
213     else
214     {
215     cur_obj = obj_stack.top ();
216     obj_stack.pop ();
217     }
218     }
219     else
220     execute_child (*i, l);
221     }
222     }
223    
224     void turtle_interpreter::operator ()(const module_vec &v, const lsys &l) t_err
225     {
226     cur.pos = vec(0, 0, 0);
227     cur.dir = mat (vec ( 0, 1, 0),
228     vec ( 1, 0, 0),
229     vec ( 0, 0, 1));
230    
231     srand (1); // zero breaks certain libc versins
232    
233     cur.attr["delta"] = 45.0;
234     cur.attr["distance"] = 10.0;
235     attrs_changed ();
236    
237     iface.begin_fig ();
238     execute (v, l);
239     iface.end_fig ();
240     }
241