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, 5 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Log Message:
*** empty log message ***

File Contents

# Content
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