24cc04722a7a50c4ef10d97140058534c670cb8f
[lsystem3d.git] / src / rule.cpp
1 // Copyright (C) 2006 Erik Dahlberg
2 //
3 // This file is part of LSystem3D.
4 //
5 // LSystem3D is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // LSystem3D is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with LSystem3D; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
22 #include <cstdlib>
23
24 #include <sstream>
25 #include <string>
26
27 #include "rule.h"
28
29 using namespace std;
30
31
32
33 /**
34 * Constructor
35 */
36 Rule::Rule()
37 {
38 clear();
39 }
40
41
42
43 /**
44 * Constructor
45 * @param name name of rule
46 * @param content content of rule
47 * @param probability probability of rule
48 */
49 Rule::Rule(string name, string content, double probability)
50 {
51 setName(name);
52 setContent(content);
53 setProbability(probability);
54 }
55
56
57
58 /**
59 * Constructor
60 * @param ruleString the rule string
61 */
62 Rule::Rule(string ruleString)
63 {
64 fromString(ruleString);
65 }
66
67
68
69 /**
70 * Destructor
71 */
72 Rule::~Rule()
73 {
74 }
75
76
77
78 /**
79 * Clear rule
80 */
81 void Rule::clear()
82 {
83 _name.clear();
84 _content.clear();
85 _probability = 0.0;
86 }
87
88
89
90 /**
91 * Construct rule from string
92 * @param ruleString the rule string
93 */
94 void Rule::fromString(string ruleString)
95 {
96 // name
97 setName(ruleString.substr(0, 1));
98
99
100 // probability factor
101
102 int i = 2;
103
104 if (ruleString[1] == '=')
105 {
106 // use default probability
107 setProbability(1.0);
108 }
109 else if (ruleString[1] == '(')
110 {
111 // set probability
112 while (ruleString[i] != ')')
113 {
114 i++;
115 }
116
117 setProbability(strtod(string(ruleString, 2, i - 2).c_str(), NULL));
118
119 // ignore the '='
120 i += 2;
121 }
122
123 // content
124 setContent(string(ruleString, i));
125 }
126
127
128
129 /**
130 * Construct rule string
131 * @return the rule string
132 */
133 string Rule::toString()
134 {
135 // name
136 string rulesString = getName();
137
138
139 // probability factor
140
141 if (_probability > 0.0 && _probability < 1.0)
142 {
143 ostringstream probabilityString;
144 probabilityString << getProbability();
145
146 // TODO: precision
147 rulesString += '(';
148 rulesString += string(probabilityString.str(), 0, 4);
149 rulesString += ')';
150 }
151
152
153 rulesString += '=';
154
155
156 // content
157 rulesString += getContent();
158
159
160 return rulesString;
161 }
162
163
164
165 /**
166 * Set rule name
167 * @param name the name
168 */
169 void Rule::setName(string name)
170 {
171 _name = name;
172 }
173
174
175
176 /**
177 * Set rule content
178 * @param content the content
179 */
180 void Rule::setContent(string content)
181 {
182 string preprocessedRule;
183
184 // preprocess the rule content
185 for (int i = 0; i < content.size(); i++)
186 {
187 // TODO: allow string as name
188 if (content[i] >= 'A' && content[i] <= 'Z' && content[i] != 'F')
189 {
190 // add rule operator
191 preprocessedRule += '@';
192 }
193 preprocessedRule += content[i];
194 }
195
196 _content = preprocessedRule;
197 }
198
199
200
201 /**
202 * Set rule probability
203 * @param probability the probability factor
204 */
205 void Rule::setProbability(double probability)
206 {
207 if (probability >= 0 && probability <= 1)
208 {
209 _probability = probability;
210 }
211 else
212 {
213 probability = 0.0;
214 }
215 }
216
217
218
219 /**
220 * Get rule name
221 * @return the rule name
222 */
223 string Rule::getName()
224 {
225 return _name;
226 }
227
228
229
230 /**
231 * Get rule content
232 * @return the rule content
233 */
234 string Rule::getContent()
235 {
236 string unpreprocessedRule;
237
238 // unpreprocess the rule content
239 for (int i = 0; i < _content.size(); i++)
240 {
241 if (_content[i] != '@')
242 {
243 unpreprocessedRule += _content[i];
244 }
245 }
246
247 return unpreprocessedRule;
248 }
249
250
251
252 /**
253 * Get rule probability
254 * @return the probability
255 */
256 double Rule::getProbability()
257 {
258 return _probability;
259 }
260
261
262
263 /**
264 * Get preprocessed content
265 * @return the preprocessed content
266 */
267 string Rule::getPreprocessedContent()
268 {
269 return _content;
270 }