--- /dev/null
+// Copyright (C) 2006 Erik Dahlberg
+//
+// This file is part of LSystem3D.
+//
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+
+
+#include <string>
+
+#include <glibmm/stringutils.h>
+
+#include "rule.h"
+
+using namespace std;
+
+
+
+/**
+ * Constructor
+ */
+Rule::Rule()
+{
+ clear();
+}
+
+
+
+/**
+ * Constructor
+ * @param name name of rule
+ * @param content content of rule
+ * @param probability probability of rule
+ */
+Rule::Rule(string name, string content, double probability)
+{
+ setName(name);
+ setContent(content);
+ setProbability(probability);
+}
+
+
+
+/**
+ * Constructor
+ * @param ruleString the rule string
+ */
+Rule::Rule(string ruleString)
+{
+ fromString(ruleString);
+}
+
+
+
+/**
+ * Destructor
+ */
+Rule::~Rule()
+{
+}
+
+
+
+/**
+ * Clear rule
+ */
+void Rule::clear()
+{
+ _name.clear();
+ _content.clear();
+ _probability = 0.0;
+}
+
+
+
+/**
+ * Construct rule from string
+ * @param ruleString the rule string
+ */
+void Rule::fromString(string ruleString)
+{
+ // name
+ setName(ruleString.substr(0, 1));
+
+
+ // probability factor
+
+ int i = 2;
+
+ if (ruleString[1] == '=')
+ {
+ // use default probability
+ setProbability(1.0);
+ }
+ else if (ruleString[1] == '(')
+ {
+ // set probability
+ while (ruleString[i] != ')')
+ {
+ i++;
+ }
+ setProbability(Glib::Ascii::strtod(string(ruleString, 2, i - 2)));
+
+ // ignore the '='
+ i += 2;
+ }
+
+ // content
+ setContent(string(ruleString, i));
+}
+
+
+
+/**
+ * Construct rule string
+ * @return the rule string
+ */
+string Rule::toString()
+{
+ // name
+ string rulesString = getName();
+
+
+ // probability factor
+
+ if (_probability != 0.0)
+ {
+ // TODO: precision
+ string probabilityString(Glib::Ascii::dtostr(getProbability()), 0, 4);
+
+ rulesString += '(';
+ rulesString += probabilityString;
+ rulesString += ')';
+ }
+
+
+ rulesString += '=';
+
+
+ // content
+ rulesString += getContent();
+
+
+ return rulesString;
+}
+
+
+
+/**
+ * Set rule name
+ * @param name the name
+ */
+void Rule::setName(string name)
+{
+ _name = name;
+}
+
+
+
+/**
+ * Set rule content
+ * @param content the content
+ */
+void Rule::setContent(string content)
+{
+ string preprocessedRule;
+
+ // preprocess the rule content
+ for (int i = 0; i < content.size(); i++)
+ {
+ // TODO: allow string as name
+ if (content[i] >= 'A' && content[i] <= 'Z' && content[i] != 'F')
+ {
+ // add rule operator
+ preprocessedRule += '@';
+ }
+ preprocessedRule += content[i];
+ }
+
+ _content = preprocessedRule;
+}
+
+
+
+/**
+ * Set rule probability
+ * @param probability the probability factor
+ */
+void Rule::setProbability(double probability)
+{
+ if (probability >= 0 && probability <= 1)
+ {
+ _probability = probability;
+ }
+ else
+ {
+ probability = 0.0;
+ }
+}
+
+
+
+/**
+ * Get rule name
+ * @return the rule name
+ */
+string Rule::getName()
+{
+ return _name;
+}
+
+
+
+/**
+ * Get rule content
+ * @return the rule content
+ */
+string Rule::getContent()
+{
+ string unpreprocessedRule;
+
+ // unpreprocess the rule content
+ for (int i = 0; i < _content.size(); i++)
+ {
+ if (_content[i] != '@')
+ {
+ unpreprocessedRule += _content[i];
+ }
+ }
+
+ return unpreprocessedRule;
+}
+
+
+
+/**
+ * Get rule probability
+ * @return the probability
+ */
+double Rule::getProbability()
+{
+ return _probability;
+}
+
+
+
+/**
+ * Get preprocessed content
+ * @return the preprocessed content
+ */
+string Rule::getPreprocessedContent()
+{
+ return _content;
+}
--- /dev/null
+// Copyright (C) 2006 Erik Dahlberg
+//
+// This file is part of LSystem3D.
+//
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+
+
+#ifndef RULE_H
+#define RULE_H
+
+#include <string>
+
+using namespace std;
+
+
+
+/**
+ * L-system rule
+ */
+class Rule
+{
+public:
+
+ /**
+ * Constructor
+ */
+ Rule();
+
+ /**
+ * Constructor
+ * @param name name of rule
+ * @param content content of rule
+ * @param probability probability of rule
+ */
+ Rule(string name, string content, double probability);
+
+ /**
+ * Constructor
+ * @param ruleString the rule string
+ */
+ Rule(string ruleString);
+
+ /**
+ * Destructor
+ */
+ ~Rule();
+
+ /**
+ * Clear rule
+ */
+ void clear();
+
+ /**
+ * Construct rule from string
+ * @param ruleString the rule string
+ */
+ void fromString(string ruleString);
+
+ /**
+ * Construct rule string
+ * @return the rule string
+ */
+ string toString();
+
+ /**
+ * Set rule name
+ * @param name the name
+ */
+ void setName(string name);
+
+ /**
+ * Set rule content
+ * @param content the content
+ */
+ void setContent(string content);
+
+ /**
+ * Set rule probability
+ * @param probability the probability factor
+ */
+ void setProbability(double probability);
+
+ /**
+ * Get rule name
+ * @return the rule name
+ */
+ string getName();
+
+ /**
+ * Get rule content
+ * @return the rule content
+ */
+ string getContent();
+
+ /**
+ * Get rule probability
+ * @return the probability
+ */
+ double getProbability();
+
+ /**
+ * Get preprocessed content
+ * @return the preprocessed content
+ */
+ string getPreprocessedContent();
+
+protected:
+
+ string _name;
+ string _content;
+ double _probability;
+};
+
+
+
+#endif
--- /dev/null
+// Copyright (C) 2006 Erik Dahlberg
+//
+// This file is part of LSystem3D.
+//
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+
+
+#include <cmath>
+#include <ctime>
+
+#include <string>
+#include <utility>
+
+#include "rule.h"
+#include "ruleset.h"
+
+
+
+/**
+ * Constructor
+ */
+RuleSet::RuleSet()
+{
+ srand(time(NULL));
+}
+
+
+
+/**
+ * Destructor
+ */
+RuleSet::~RuleSet()
+{
+}
+
+
+
+/**
+ * Clear rule set
+ */
+void RuleSet::clear()
+{
+ _rules.clear();
+}
+
+
+
+/**
+ * Add one rule
+ * @param rule the rule
+ */
+void RuleSet::addRule(Rule rule)
+{
+ _rules.insert(make_pair(rule.getName(), rule));
+}
+
+
+
+/**
+ * Get one rule with repect of probability factor
+ * @param name the rule name
+ * @return the rule
+ */
+Rule RuleSet::findRule(string ruleName)
+{
+ // TODO: clean up...
+
+
+ int numRules = _rules.count(ruleName);
+ Rule selectedRule;
+
+ if (numRules == 0)
+ {
+ // no rule with this name
+ selectedRule.setProbability(0.0);
+ }
+ else if (numRules == 1)
+ {
+ // only one rule with this name
+ selectedRule = _rules.find(ruleName)->second;
+ }
+ else
+ {
+ // many rules with this name
+
+
+ // find ranges
+
+ // TODO: int ok?
+ int ranges[numRules + 1];
+
+ double lastRange = ranges[0] = 0;
+ int index = 1;
+
+ // TODO: move to addRule()
+ pair<rulemap::iterator, rulemap::iterator> interval = _rules.equal_range(ruleName);
+ for (rulemap::iterator it = interval.first; it != interval.second; it++)
+ {
+ // calculate and store ranges
+ lastRange += it->second.getProbability() * RAND_MAX;
+ ranges[index++] = (int)lastRange;
+ }
+
+ ranges[numRules] = RAND_MAX;
+
+
+ // choose random range
+
+ int selection = 0;
+ int random = rand();
+
+ for (int i = 0; i < numRules; i++)
+ {
+ if (random >= ranges[i] && random <= ranges[i + 1])
+ {
+ // in range
+ selection = i;
+
+ break;
+ }
+ }
+
+
+ // make selection
+
+ rulemap::iterator it = interval.first;
+ for (int i = 0; i < selection; i++)
+ {
+ it++;
+ }
+ selectedRule = it->second;
+ }
+
+
+ return selectedRule;
+}
+
+
+
+/**
+ * Get all rules
+ * @return the rules
+ */
+rulemap RuleSet::getRules()
+{
+ return _rules;
+}
--- /dev/null
+// Copyright (C) 2006 Erik Dahlberg
+//
+// This file is part of LSystem3D.
+//
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+
+
+#ifndef RULESET_H
+#define RULESET_H
+
+#include <map>
+#include <string>
+
+#include "rule.h"
+
+using namespace std;
+
+typedef multimap<string, Rule> rulemap;
+
+
+
+/**
+ * Set of L-system rules
+ */
+class RuleSet
+{
+public:
+
+ /**
+ * Constructor
+ */
+ RuleSet();
+
+ /**
+ * Destructor
+ */
+ ~RuleSet();
+
+ /**
+ * Clear rule set
+ */
+ void clear();
+
+ /**
+ * Add one rule
+ * @param rule the rule
+ */
+ void addRule(Rule rule);
+
+ /**
+ * Get one rule with repect of probability factor
+ * @param name the rule name
+ * @return the rule
+ */
+ Rule findRule(string ruleName);
+
+ /**
+ * Get all rules
+ * @return the rules
+ */
+ rulemap getRules();
+
+protected:
+
+ rulemap _rules;
+};
+
+
+
+#endif