X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flindenmayersystem.cpp;h=18339122df83c5e9b8938c7f8bdd73d5568e21ce;hb=acf054bffd0737f5bef7fc3eba35d6a912e7c801;hp=c0fd3a727e1cfff98034b3c940f275a9c90056ca;hpb=e017b5ae9b4c9678d5464a9ff44e02ea44ae4759;p=lsystem3d.git diff --git a/src/lindenmayersystem.cpp b/src/lindenmayersystem.cpp index c0fd3a7..1833912 100644 --- a/src/lindenmayersystem.cpp +++ b/src/lindenmayersystem.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2006 Erik Dahlberg // -// This file is part of LSystem3d. +// 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 @@ -21,13 +21,16 @@ #include -#include #include #include "lindenmayersystem.h" #include "model.h" +#include "rule.h" +#include "ruleset.h" #include "turtle.h" +using namespace std; + /** @@ -62,7 +65,7 @@ void LindenmayerSystem::clear() _axiom.clear(); _rules.clear(); _turtle->setAngle(0.0); - _numIterations = 0; + _depth = 0; _turtle->reset(); _model->clear(); @@ -78,31 +81,40 @@ void LindenmayerSystem::generate() // model session _model->begin(); _model->setColorIndex(0); - recursiveWalk(_axiom, _numIterations); + recursiveWalk(_axiom.getPreprocessedContent(), _depth); _model->end(); } +/** + * Render L-system data + */ +void LindenmayerSystem::render() +{ + _model->draw(); +} + + + /** * Set the initial rule (the axiom) * @param axiom the axiom */ -void LindenmayerSystem::setAxiom(string axiom) +void LindenmayerSystem::setAxiom(Rule axiom) { - _axiom = verifyAndPreprocessRule(axiom); + _axiom = axiom; } /** * Set one rule - * @param name rule name * @param rule the rule */ -void LindenmayerSystem::setRule(string name, string rule) +void LindenmayerSystem::setRule(Rule rule) { - _rules[name] = verifyAndPreprocessRule(rule); + _rules.addRule(rule); } @@ -122,29 +134,30 @@ void LindenmayerSystem::setAngle(double degrees) /** - * Set the number of iterations - * @param numIterations number of iterations + * Set recursion depth + * @param depth depth of recursion */ -void LindenmayerSystem::setNumIterations(int numIterations) +void LindenmayerSystem::setDepth(int depth) { - _numIterations = numIterations; + _depth = depth; } /** - * Set diameter of segment + * Set initial segment diameter * @param diameter the diameter */ void LindenmayerSystem::setDiameter(double diameter) { + _segmentDiameter = diameter; _model->setDiameter(diameter); } /** - * Set diameter factor + * Set segment diameter factor * @param diameterFactor the diameter factor */ void LindenmayerSystem::setDiameterFactor(double diameterFactor) @@ -158,9 +171,9 @@ void LindenmayerSystem::setDiameterFactor(double diameterFactor) * Get the initial rule (the axiom) * @return the axiom */ -string LindenmayerSystem::getAxiom() +Rule LindenmayerSystem::getAxiom() { - return unpreprocessRule(_axiom); + return _axiom; } @@ -169,18 +182,9 @@ string LindenmayerSystem::getAxiom() * Get all rules * @return the rules */ -map LindenmayerSystem::getRules() +RuleSet LindenmayerSystem::getRules() { - map theUnpreprocessedRules; - - // unpreprocess all rules - map::iterator currentRule; - for (currentRule = _rules.begin(); currentRule != _rules.end(); currentRule++) - { - theUnpreprocessedRules[currentRule->first] = unpreprocessRule(currentRule->second); - } - - return theUnpreprocessedRules; + return _rules; } @@ -202,30 +206,41 @@ double LindenmayerSystem::getAngle() /** - * Get the number of iterations - * @return number of iterations + * Get recursion depth + * @return depth of recursion */ -int LindenmayerSystem::getNumIterations() +int LindenmayerSystem::getDepth() { - return _numIterations; + return _depth; } /** - * Get the generated model - * @return generated model + * Get initial segment diameter + * @return the diameter */ -Model *LindenmayerSystem::getModel() +double LindenmayerSystem::getDiameter() { - return _model; + return _segmentDiameter; +} + + + +/** + * Get segment diameter factor + * @return the diameter factor + */ +double LindenmayerSystem::getDiameterFactor() +{ + return _model->getDiameterFactor(); } /** * Recursively apply the replacement rules - * @param rule rule + * @param rule the rule * @param level recursion level */ void LindenmayerSystem::recursiveWalk(string rule, int level) @@ -244,8 +259,8 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) // recursion if (level > 0) { - char ruleName[] = {rule[i], '\0'}; - recursiveWalk(_rules[ruleName], level - 1); + string name = rule.substr(i, 1); + recursiveWalk(_rules.findRule(name).getPreprocessedContent(), level - 1); } break; @@ -254,17 +269,20 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) // walk / rule case 'F': - // replacement rule for 'F'? - if (_rules.count("F") != 0 && level > 0) { - recursiveWalk(_rules["F"], level - 1); - } - else - { - // no rule for "F" - _turtle->walk(); - } - + // replacement rule for 'F'? + Rule rule = _rules.findRule("F"); + if (rule.getProbability() != 0.0 && level > 0) + { + recursiveWalk(rule.getPreprocessedContent(), level - 1); + } + else + { + // no rule for "F" + _turtle->walk(); + } + } + break; @@ -324,7 +342,7 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) break; - // restore state from stack + // load state from stack case ']': _turtle->pop(); @@ -352,7 +370,7 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) break; - // decrement diameter of segment + // decrement segment diameter case '!': _model->decrementDiameter(); @@ -374,55 +392,3 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) } } } - - - -/** - * Verify and preprocess one rule string - * @param rule the rule - * @return the preprocessed rule - */ -string LindenmayerSystem::verifyAndPreprocessRule(string rule) -{ - // TODO: verifying - - string preprocessedRule; - - // check every element in rule - for (int i = 0; i < rule.size(); i++) - { - // TODO: allow strings as names - if (rule[i] >= 'A' && rule[i] <= 'Z' && rule[i] != 'F') - { - // add rule operator - preprocessedRule += '@'; - } - preprocessedRule += rule[i]; - } - - return preprocessedRule; -} - - - -/** - * Unpreprocess one rule string - * @param rule the rule - * @return the unpreprocessed rule - */ -string LindenmayerSystem::unpreprocessRule(string rule) -{ - string unpreprocessedRule; - - // check every element in rule - for (int i = 0; i < rule.size(); i++) - { - // ignore rule operator - if (rule[i] != '@') - { - unpreprocessedRule += rule[i]; - } - } - - return unpreprocessedRule; -}