initial revision
authorspixx <spixx>
Sat, 11 Nov 2006 13:23:29 +0000 (13:23 +0000)
committerspixx <spixx>
Sat, 11 Nov 2006 13:23:29 +0000 (13:23 +0000)
src/rule.cpp [new file with mode: 0644]
src/rule.h [new file with mode: 0644]
src/ruleset.cpp [new file with mode: 0644]
src/ruleset.h [new file with mode: 0644]

diff --git a/src/rule.cpp b/src/rule.cpp
new file mode 100644 (file)
index 0000000..564aa2c
--- /dev/null
@@ -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 <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;
+}
diff --git a/src/rule.h b/src/rule.h
new file mode 100644 (file)
index 0000000..fcef31f
--- /dev/null
@@ -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 <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
diff --git a/src/ruleset.cpp b/src/ruleset.cpp
new file mode 100644 (file)
index 0000000..024f77e
--- /dev/null
@@ -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 <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;
+}
diff --git a/src/ruleset.h b/src/ruleset.h
new file mode 100644 (file)
index 0000000..63575a5
--- /dev/null
@@ -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 <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