From 71fe848416e50bea3b6484345047b0379126508b Mon Sep 17 00:00:00 2001 From: spixx Date: Sat, 11 Nov 2006 13:23:29 +0000 Subject: [PATCH] initial revision --- src/rule.cpp | 267 ++++++++++++++++++++++++++++++++++++++++++++++++ src/rule.h | 130 +++++++++++++++++++++++ src/ruleset.cpp | 161 +++++++++++++++++++++++++++++ src/ruleset.h | 84 +++++++++++++++ 4 files changed, 642 insertions(+) create mode 100644 src/rule.cpp create mode 100644 src/rule.h create mode 100644 src/ruleset.cpp create mode 100644 src/ruleset.h diff --git a/src/rule.cpp b/src/rule.cpp new file mode 100644 index 0000000..564aa2c --- /dev/null +++ b/src/rule.cpp @@ -0,0 +1,267 @@ +// 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 + +#include + +#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; +} diff --git a/src/rule.h b/src/rule.h new file mode 100644 index 0000000..fcef31f --- /dev/null +++ b/src/rule.h @@ -0,0 +1,130 @@ +// 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 + +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 diff --git a/src/ruleset.cpp b/src/ruleset.cpp new file mode 100644 index 0000000..024f77e --- /dev/null +++ b/src/ruleset.cpp @@ -0,0 +1,161 @@ +// 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 +#include + +#include +#include + +#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 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; +} diff --git a/src/ruleset.h b/src/ruleset.h new file mode 100644 index 0000000..63575a5 --- /dev/null +++ b/src/ruleset.h @@ -0,0 +1,84 @@ +// 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 +#include + +#include "rule.h" + +using namespace std; + +typedef multimap 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 -- 2.34.1