From 526db67540bf69a4c09ed0d0f4d62bad0a37ee70 Mon Sep 17 00:00:00 2001 From: spixx Date: Sat, 4 Nov 2006 19:30:01 +0000 Subject: [PATCH] *** empty log message *** --- src/Makefile.am | 17 ++-- src/coordinate.cpp | 30 +++--- src/coordinate.h | 17 ++-- src/lindenmayersystem.cpp | 162 ++++++++++++++++++++---------- src/lindenmayersystem.h | 50 +++++++--- src/lsystem.cpp | 11 +-- src/lsystem.xml | 14 ++- src/lsystemparameters.cpp | 8 +- src/lsystemparameters.h | 6 +- src/model.cpp | 201 +++++++++++++++++++++++++++++++------- src/model.h | 94 +++++++++++++++--- src/turtle.cpp | 115 ++++++++++------------ src/turtle.h | 49 ++++------ src/vector.cpp | 6 +- src/vector.h | 6 +- src/xmlstructure.cpp | 2 +- 16 files changed, 519 insertions(+), 269 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 909976e..ed9bc07 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,13 +1,14 @@ bin_PROGRAMS = lsystem3d -lsystem3d_SOURCES = lsystem.cpp callbacks.cpp lindenmayersystem.cpp model.cpp \ - openglwindow.cpp turtle.cpp vector.cpp xmlstructure.cpp lsystemparameters.cpp \ - coordinate.cpp +lsystem3d_SOURCES = lsystem.cpp lindenmayersystem.cpp model.cpp turtle.cpp \ + vector.cpp xmlstructure.cpp lsystemparameters.cpp coordinate.cpp lsystem3d.cpp \ + renderingsurface.cpp gui.cpp color.cpp # set the include path found by configure -INCLUDES = `pkg-config libxml++-2.6 --cflags` $(all_includes) +INCLUDES = `fox-config --cflags` `pkg-config libxml++-2.6 --cflags` \ + $(all_includes) # the library search path. -lsystem3d_LDFLAGS = $(all_libraries) -lglui -lglut -lGLU -lGL `pkg-config \ - libxml++-2.6 --libs` -noinst_HEADERS = callbacks.h lindenmayersystem.h model.h openglwindow.h \ - turtle.h vector.h xmlstructure.h lsystemparameters.h coordinate.h lsystem.xml +lsystem3d_LDFLAGS = $(all_libraries) `pkg-config libxml++-2.6 --libs` \ + `fox-config --libs` +noinst_HEADERS = lindenmayersystem.h model.h turtle.h vector.h xmlstructure.h \ + lsystemparameters.h coordinate.h lsystem.xml lsystem3d.h renderingsurface.h gui.h color.h diff --git a/src/coordinate.cpp b/src/coordinate.cpp index 026addb..ffef1c7 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -42,6 +42,21 @@ Coordinate::~Coordinate() +/** + * Set coordinate + * @param x the x-coordinate + * @param y the y-coordinate + * @param z the z-coordinate + */ +void Coordinate::setXYZ(double x, double y, double z) +{ + _x = x; + _y = y; + _z = z; +} + + + /** * Get x-coordinate * @return the x-coordinate @@ -72,18 +87,3 @@ double Coordinate::getZ() { return _z; } - - - -/** - * Set coordinate - * @param x the x-coordinate - * @param y the y-coordinate - * @param z the z-coordinate - */ -void Coordinate::setXYZ(double x, double y, double z) -{ - _x = x; - _y = y; - _z = z; -} diff --git a/src/coordinate.h b/src/coordinate.h index cac2a1a..70c990a 100644 --- a/src/coordinate.h +++ b/src/coordinate.h @@ -30,6 +30,7 @@ class Coordinate { public: + /** * Constructor */ @@ -40,6 +41,14 @@ public: */ ~Coordinate(); + /** + * Set coordinate + * @param x the x-coordinate + * @param y the y-coordinate + * @param z the z-coordinate + */ + void setXYZ(double x, double y, double z); + /** * Get x-coordinate * @return the x-coordinate @@ -57,14 +66,6 @@ public: * @return the z-coordinate */ double getZ(); - - /** - * Set coordinate - * @param x the x-coordinate - * @param y the y-coordinate - * @param z the z-coordinate - */ - void setXYZ(double x, double y, double z); protected: diff --git a/src/lindenmayersystem.cpp b/src/lindenmayersystem.cpp index 9a66023..a401634 100644 --- a/src/lindenmayersystem.cpp +++ b/src/lindenmayersystem.cpp @@ -22,29 +22,24 @@ #include #include -#include #include #include "lindenmayersystem.h" #include "model.h" #include "turtle.h" -using namespace std; - /** * Constructor - * @param model the model for generation + * @param model empty model */ LindenmayerSystem::LindenmayerSystem(Model *model) { _model = model; _turtle = new Turtle(model); - _axiom.clear(); - _rules.clear(); - _numIterations = 0; + clear(); } @@ -59,6 +54,36 @@ LindenmayerSystem::~LindenmayerSystem() +/** + * Clear all parameters + */ +void LindenmayerSystem::clear() +{ + _axiom.clear(); + _rules.clear(); + _turtle->setAngle(0.0); + _numIterations = 0; + + _turtle->reset(); + _model->clear(); +} + + + +/** + * Generate L-system data + */ +void LindenmayerSystem::generate() +{ + // model session + _model->begin(); + _model->setColorIndex(0); + recursiveWalk(_axiom, _numIterations); + _model->end(); +} + + + /** * Set the initial rule (the axiom) * @param axiom the axiom @@ -107,6 +132,28 @@ void LindenmayerSystem::setNumIterations(int numIterations) +/** + * Set diameter of segment + * @param diameter the diameter + */ +void LindenmayerSystem::setDiameter(double diameter) +{ + _model->setDiameter(diameter); +} + + + +/** + * Set diameter factor + * @param diameterFactor the diameter factor + */ +void LindenmayerSystem::setDiameterFactor(double diameterFactor) +{ + _model->setDiameterFactor(diameterFactor); +} + + + /** * Get the initial rule (the axiom) * @return the axiom @@ -166,52 +213,58 @@ int LindenmayerSystem::getNumIterations() /** - * Generate l-system data + * Get the generated model + * @return generated model */ -void LindenmayerSystem::generate() +Model *LindenmayerSystem::getModel() { - _model->clear(); - - recursiveWalk(_axiom, _numIterations); - - _turtle->reset(); + return _model; } /** - * Walk through the rule string for specified number of levels - * @param rule the rule - * @param level current iteration level + * Recursively apply the replacement rules + * @param rule rule + * @param level recursion level */ void LindenmayerSystem::recursiveWalk(string rule, int level) { - // Process every element in the rule string + // process every element in the rule string for (int i = 0; i < rule.size(); i++) { switch (rule[i]) { - // walk + // rule case '@': - + // ignore marker, i.e. the "@" i++; // recursion - if (level == 0) + if (level > 0) { - // at lowest level, start rendering + char ruleName[] = {rule[i], '\0'}; + recursiveWalk(_rules[ruleName], level - 1); + } - _turtle->walk(); + break; + + + // walk / rule + case 'F': + + // replacement rule for 'F'? + if (_rules.count("F") != 0 && level > 0) + { + recursiveWalk(_rules["F"], level - 1); } else { - // more levels to go - - char ruleName[] = {rule[i], '\0'}; - recursiveWalk(_rules[ruleName], level - 1); + // no rule for "F" + _turtle->walk(); } - + break; @@ -278,39 +331,45 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) break; - // first vertex in a filled surface + // create a filled surface case '{': - _turtle->fenceInBegin(); + _model->fillBegin(); break; - // last vertex in a filled surface + // close a filled surface case '}': - _turtle->fenceInEnd(); + _model->fillEnd(); break; // one vertex in a filled surface case 'f': - _turtle->walk(); + _turtle->fillWalk(); break; // decrement diameter of segment case '!': - _turtle->decrementDiameter(); + _model->decrementDiameter(); break; - // unknown operation - default : + // increment current index to color table + case '\'': - // TODO: filter these out when preprocessing - cerr << "Unknown operator in rule string:" << rule[i] << endl; + _model->nextColor(); + break; + + + // decrement current index to color table + case '`': + + _model->prevColor(); break; } } @@ -320,26 +379,25 @@ void LindenmayerSystem::recursiveWalk(string rule, int level) /** * Verify and preprocess one rule string - * @param ruleOrAxiom the rule + * @param rule the rule * @return the preprocessed rule */ -string LindenmayerSystem::verifyAndPreprocessRule(string ruleOrAxiom) +string LindenmayerSystem::verifyAndPreprocessRule(string rule) { - // for now, simply put "@" before every rewriting operator // TODO: verifying string preprocessedRule; // check every element in rule - for (int i = 0; i < ruleOrAxiom.size(); i++) + for (int i = 0; i < rule.size(); i++) { - // TODO: remove the A-Z limit: use strings, not single chars - if (ruleOrAxiom[i] >= 'A' && ruleOrAxiom[i] <= 'Z') + // TODO: allow strings as names + if (rule[i] >= 'A' && rule[i] <= 'Z' && rule[i] != 'F') { - // mark as rewriting operator + // add rule operator preprocessedRule += '@'; } - preprocessedRule += ruleOrAxiom[i]; + preprocessedRule += rule[i]; } return preprocessedRule; @@ -349,20 +407,20 @@ string LindenmayerSystem::verifyAndPreprocessRule(string ruleOrAxiom) /** * Unpreprocess one rule string - * @param ruleOrAxiom the rule + * @param rule the rule * @return the unpreprocessed rule */ -string LindenmayerSystem::unpreprocessRule(string ruleOrAxiom) +string LindenmayerSystem::unpreprocessRule(string rule) { string unpreprocessedRule; // check every element in rule - for (int i = 0; i < ruleOrAxiom.size(); i++) + for (int i = 0; i < rule.size(); i++) { - // ignore rewriting marker - if (ruleOrAxiom[i] != '@') + // ignore rule operator + if (rule[i] != '@') { - unpreprocessedRule += ruleOrAxiom[i]; + unpreprocessedRule += rule[i]; } } diff --git a/src/lindenmayersystem.h b/src/lindenmayersystem.h index efadab9..d71fde6 100644 --- a/src/lindenmayersystem.h +++ b/src/lindenmayersystem.h @@ -28,8 +28,6 @@ #include "model.h" #include "turtle.h" -using namespace std; - /** @@ -38,9 +36,10 @@ using namespace std; class LindenmayerSystem { public: + /** * Constructor - * @param model the model for generation + * @param model empty model */ LindenmayerSystem(Model *model); @@ -49,6 +48,16 @@ public: */ ~LindenmayerSystem(); + /** + * Clear all parameters + */ + void clear(); + + /** + * Generate L-system data + */ + void generate(); + /** * Set the initial rule (the axiom) * @param axiom the axiom @@ -74,6 +83,18 @@ public: */ void setNumIterations(int numIterations); + /** + * Set diameter of segment + * @param diameter the diameter + */ + void setDiameter(double diameter); + + /** + * Set diameter factor + * @param diameterFactor the diameter factor + */ + void setDiameterFactor(double diameterFactor); + /** * Get the initial rule (the axiom) * @return the axiom @@ -99,39 +120,40 @@ public: int getNumIterations(); /** - * Generate l-system data + * Get the generated model + * @return generated model */ - void generate(); + Model *getModel(); protected: /** - * Walk through the rule string for specified number of levels - * @param rule the rule - * @param level current iteration level + * Recursively apply the replacement rules + * @param rule rule + * @param level recursion level */ void recursiveWalk(string rule, int level); /** * Verify and preprocess one rule string - * @param ruleOrAxiom the rule + * @param rule the rule * @return the preprocessed rule */ - string verifyAndPreprocessRule(string ruleOrAxiom); + string verifyAndPreprocessRule(string rule); /** * Unpreprocess one rule string - * @param ruleOrAxiom the rule + * @param rule the rule * @return the unpreprocessed rule */ - string unpreprocessRule(string ruleOrAxiom); + string unpreprocessRule(string rule); // Parameters string _axiom; - map _rules; // TODO: use unsorted container? + map _rules; // TODO: use unsorted container? int _numIterations; - Model *_model; // The model for generation + Model *_model; // The active model Turtle *_turtle; // The rendering turtle }; diff --git a/src/lsystem.cpp b/src/lsystem.cpp index 27e51d3..cb9b2ca 100644 --- a/src/lsystem.cpp +++ b/src/lsystem.cpp @@ -25,20 +25,13 @@ #include -#include - -#include "openglwindow.h" - - -OpenGLWindow *openglWindow = NULL; +#include "lsystem3d.h" int main(int argc, char *argv[]) { - glutInit(&argc, argv); - - OpenGLWindow window; + LSystem3D lsystem3d(argc, argv); return EXIT_SUCCESS; diff --git a/src/lsystem.xml b/src/lsystem.xml index 803a809..6c83289 100644 --- a/src/lsystem.xml +++ b/src/lsystem.xml @@ -1,7 +1,13 @@ - A - A/[!+A&A]/A - 30.0 - 4 + P + FF + FS[//&&L][//^^L]FS! + [`{-f+ff+f-|-f+ff+f}] + [&&&E'/W////W////W////W////W] + I+[P+O]--//[--L]I[++L]-[PO]++PO + SFS + ['^F][{&&&&-f+f|-f+f}] + 18.0 + 6 diff --git a/src/lsystemparameters.cpp b/src/lsystemparameters.cpp index c12e9e3..bdd16eb 100644 --- a/src/lsystemparameters.cpp +++ b/src/lsystemparameters.cpp @@ -48,7 +48,7 @@ LSystemParameters::~LSystemParameters() /** * Load parameters from xml file - * @param lsystem put parameters into this l-system + * @param lsystem put parameters into this L-system * @param path path to xml file */ void LSystemParameters::load(LindenmayerSystem *lsystem, string path) @@ -88,7 +88,7 @@ void LSystemParameters::load(LindenmayerSystem *lsystem, string path) } else { - cerr << "invalid lsystem" << endl; + cerr << "invalid L-system" << endl; } } @@ -96,7 +96,7 @@ void LSystemParameters::load(LindenmayerSystem *lsystem, string path) /** * Save parameters to xml file - * @param lsystem get parameters from this l-system + * @param lsystem get parameters from this L-system * @param path path to xml file */ void LSystemParameters::save(LindenmayerSystem *lsystem, string path) @@ -133,6 +133,6 @@ void LSystemParameters::save(LindenmayerSystem *lsystem, string path) } else { - cerr << "invalid lsystem" << endl; + cerr << "invalid L-system" << endl; } } diff --git a/src/lsystemparameters.h b/src/lsystemparameters.h index 1d80635..e09bb45 100644 --- a/src/lsystemparameters.h +++ b/src/lsystemparameters.h @@ -32,7 +32,7 @@ using namespace std; /** - * Save and load a l-system specification + * Save and load a L-system specification */ class LSystemParameters : protected XMLStructure { @@ -49,14 +49,14 @@ public: /** * Load parameters from xml file - * @param lsystem put parameters into this l-system + * @param lsystem put parameters into this L-system * @param path path to xml file */ void load(LindenmayerSystem *lsystem, string path); /** * Save parameters to xml file - * @param lsystem get parameters from this l-system + * @param lsystem get parameters from this L-system * @param path path to xml file */ void save(LindenmayerSystem *lsystem, string path); diff --git a/src/model.cpp b/src/model.cpp index 48308a0..9a8554b 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -19,9 +19,12 @@ +#include + #include "GL/gl.h" #include "GL/glu.h" +#include "color.h" #include "model.h" #include "vector.h" @@ -32,7 +35,14 @@ */ Model::Model() { - _displayList = glGenLists(1); + // default color table + Color brown(0.5, 0.2, 0.0); _colorTable.push_back(brown); + Color white(1.0, 1.0, 1.0); _colorTable.push_back(white); + Color green(0.0, 0.5, 0.0); _colorTable.push_back(green); + + _displayList = 0; + + clear(); } @@ -48,8 +58,7 @@ Model::~Model() /** - * Connect two points - * @param diameter diameter of segment + * Create a segment * @param x1 x start point * @param y1 y start point * @param z1 z start point @@ -57,53 +66,65 @@ Model::~Model() * @param y2 y end point * @param z2 z end point */ -void Model::segment(double diameter, double x1, double y1, double z1, double x2, double y2, double z2) +void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2) { - // wireframe - // - // glColor3f(1,1,1); - // glBegin(GL_LINES); - // glVertex3d(x1, y1, z1); - // glVertex3d(x2, y2, z2); - // glEnd(); - - - - // solid - - // find rotation vector and angle of cylinder + // find rotation vector and angle Vector initial(0.0, 1.0, 0.0); // initial rotation of cylinder Vector desired(x2-x1, y2-y1, z2-z1); // desired rotation of cylinder desired.normalize(); // rotation angle - double angle = initial.getAngle(desired); + double rotationAngle = initial.getAngle(desired); // rotation vector - Vector crossProduct = initial.getCrossProduct(desired); - crossProduct.normalize(); + Vector rotationVector = initial.getCrossProduct(desired); + rotationVector.normalize(); // render the cylinder - GLUquadric *quadric = gluNewQuadric(); + static GLUquadric *quadric = gluNewQuadric(); - glColor3f(1.0, 0.5, 0.0); - glPushMatrix(); glTranslatef(x1, y1, z1); - glRotatef(angle, crossProduct.getX(), crossProduct.getY(), crossProduct.getZ()); + glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ()); glRotatef(-90, 1, 0, 0); - gluCylinder(quadric, diameter, diameter, 1.0, 6, 6); + gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6); glPopMatrix(); } /** - * Draw model to screen + * Specify a vertex + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + */ +void Model::vertex(double x, double y, double z) +{ + glVertex3d(x, y, z); +} + + + +/** + * Specify a normal + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + */ +void Model::normal(double x, double y, double z) +{ + glNormal3f(x, y, z); +} + + + +/** + * Render to screen */ void Model::draw() { @@ -117,13 +138,19 @@ void Model::draw() */ void Model::clear() { - // TODO: not needed? + glDeleteLists(_displayList, 1); + _displayList = glGenLists(1); + + setColorIndex(0); + + _diameter = 0.1; + _diameterFactor = 0.8; } /** - * Start recording of drawing operations + * Begin a modelling session */ void Model::begin() { @@ -133,7 +160,7 @@ void Model::begin() /** - * Stop recording of drawing operations + * End a modelling session */ void Model::end() { @@ -143,33 +170,131 @@ void Model::end() /** - * Begin creation of a filled surface + * Begin creation of a filled polygon */ void Model::fillBegin() { - glColor3f(0.0, 0.5, 0.0); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + glBegin(GL_POLYGON); } /** - * End creation of a filled surface + * End creation of a filled polygon */ void Model::fillEnd() { glEnd(); + + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); } /** - * Create one vertex in the filled surface - * @param x x-coordinate - * @param y y-coordinate - * @param z z-coordinate + * Increment current index to color table */ -void Model::point(double x, double y, double z) +void Model::nextColor() { - glVertex3d(x, y, z); + setColorIndex(_colorIndex + 1); +} + + + +/** + * Decrement current index to color table + */ +void Model::prevColor() +{ + setColorIndex(_colorIndex - 1); +} + + + +/** + * Decrement diameter of segment + */ +void Model::decrementDiameter() +{ + _diameter *= _diameterFactor; +} + + + +/** + * Set current color index + * @param index the color index + */ +void Model::setColorIndex(int index) +{ + // keep in range + + if (index < 0) + { + _colorIndex = _colorTable.size() - 1; + } + else if (index > (_colorTable.size() - 1)) + { + _colorIndex = 0; + } + else + { + _colorIndex = index; + } + + + // set color + + Color color = _colorTable[_colorIndex]; + double r = color.getR(); + double g = color.getG(); + double b = color.getB(); + + glColor3f(r, g, b); +} + + + +/** + * Set current diameter of segment + * @param diameter the diameter + */ +void Model::setDiameter(double diameter) +{ + _diameter = diameter; +} + + + +/** + * Set diameter factor + * @param diameter the diameter factor + */ +void Model::setDiameterFactor(double diameterFactor) +{ + _diameterFactor = diameterFactor; +} + + + +/** + * Get current color index + * @return color index + */ +int Model::getColorIndex() +{ + return _colorIndex; +} + + + +/** + * Get current diameter of segment + * @return diameter of segment + */ +double Model::getDiameter() +{ + return _diameter; } diff --git a/src/model.h b/src/model.h index d7ebf26..a05d8e3 100644 --- a/src/model.h +++ b/src/model.h @@ -22,13 +22,18 @@ #ifndef MODEL_H #define MODEL_H +#include + #include +#include "color.h" + +using namespace std; + /** - * The generated l-system model - * TODO: inheritance, i.e. Model<-OpenGLModel/WireModel/...? + * The L-system model */ class Model { @@ -44,8 +49,7 @@ public: ~Model(); /** - * Connect two points - * @param diameter diameter of segment + * Create a segment * @param x1 x start point * @param y1 y start point * @param z1 z start point @@ -53,10 +57,26 @@ public: * @param y2 y end point * @param z2 z end point */ - void segment(double diameter, double x1, double y1, double z1, double x2, double y2, double z2); + void segment(double x1, double y1, double z1, double x2, double y2, double z2); + + /** + * Specify a vertex + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + */ + void vertex(double x, double y, double z); + + /** + * Specify a normal + * @param x x-coordinate + * @param y y-coordinate + * @param z z-coordinate + */ + void normal(double x, double y, double z); /** - * Draw model to screen + * Render to screen */ void draw(); @@ -66,36 +86,78 @@ public: void clear(); /** - * Start recording of drawing operations + * Begin a modelling session */ void begin(); /** - * Stop recording of drawing operations + * End a modelling session */ void end(); /** - * Begin creation of a filled surface + * Begin creation of a filled polygon */ void fillBegin(); /** - * End creation of a filled surface + * End creation of a filled polygon */ void fillEnd(); /** - * Create one vertex in the filled surface - * @param x x-coordinate - * @param y y-coordinate - * @param z z-coordinate + * Increment current index to color table + */ + void nextColor(); + + /** + * Decrement current index to color table + */ + void prevColor(); + + /** + * Decrement diameter of segment + */ + void decrementDiameter(); + + /** + * Set current color index + * @param index the color index + */ + void setColorIndex(int index); + + /** + * Set current diameter of segment + * @param diameter the diameter */ - void point(double x, double y, double z); + void setDiameter(double diameter); + + /** + * Set diameter factor + * @param diameter the diameter factor + */ + void setDiameterFactor(double diameterFactor); + + /** + * Get current color index + * @return color index + */ + int getColorIndex(); + + /** + * Get current diameter of segment + * @return diameter of segment + */ + double getDiameter(); protected: - GLuint _displayList; // all drawing operations + GLuint _displayList; // All drawing operations + + vector _colorTable; // Color table + int _colorIndex; // Current index to color table + double _diameter; // Current diameter of segment + double _diameterFactor; // Diameter factor // TODO: "Diameter factor"? }; diff --git a/src/turtle.cpp b/src/turtle.cpp index 9847b5a..69421c8 100644 --- a/src/turtle.cpp +++ b/src/turtle.cpp @@ -28,21 +28,23 @@ #include "turtle.h" #include "vector.h" +using namespace std; + /** * Constructor - * @param model render this model + * @param model create this model */ Turtle::Turtle(Model *model) { + _model = model; + // initial position and orientation reset(); // 90 degrees _angle = M_PIl / 2.0; - - _model = model; } @@ -159,18 +161,31 @@ void Turtle::walk() // move turtle to new position _position.setXYZ(endX, endY, endZ); - if (!_fenceMode) - { - // connect the points - _model->segment(_diameter, - startX, startY, startZ, - endX, endY, endZ); - } - else - { - // part of a filled surface - _model->point(endX, endY, endZ); - } + // connect start and end point + _model->segment(startX, startY, startZ, + endX, endY, endZ); +} + + + +/** + * Walk forward, creating a filled surface + * TODO: merge with walk() ? + */ +void Turtle::fillWalk() +{ + // end point + double destinationX = _position.getX() + _heading.getX(); + double destinationY = _position.getY() + _heading.getY(); + double destinationZ = _position.getZ() + _heading.getZ(); + + _model->normal(_up.getX(), _up.getY(), _up.getZ()); + + // move turtle to new position + _position.setXYZ(destinationX, destinationY, destinationZ); + + // part of a filled polygon + _model->vertex(destinationX, destinationY, destinationZ); } @@ -189,7 +204,12 @@ void Turtle::push() _upStack.push(_up); // diameter - _diameterStack.push(_diameter); + double diameter = _model->getDiameter(); + _diameterStack.push(diameter); + + // color index + int colorIndex = _model->getColorIndex(); + _colorIndexStack.push(colorIndex); } @@ -200,15 +220,20 @@ void Turtle::push() void Turtle::pop() { // position - _position = _positionStack.top(); _positionStack.pop(); + _position = _positionStack.top(); _positionStack.pop(); // orientation - _heading = _headingStack.top(); _headingStack.pop(); - _left = _leftStack.top(); _leftStack.pop(); - _up = _upStack.top(); _upStack.pop(); + _heading = _headingStack.top(); _headingStack.pop(); + _left = _leftStack.top(); _leftStack.pop(); + _up = _upStack.top(); _upStack.pop(); // diameter - _diameter = _diameterStack.top(); _diameterStack.pop(); + double diameter = _diameterStack.top(); _diameterStack.pop(); + _model->setDiameter(diameter); + + // color index + int colorIndex = _colorIndexStack.top(); _colorIndexStack.pop(); + _model->setColorIndex(colorIndex); } @@ -217,12 +242,7 @@ void Turtle::pop() * Reset to default state */ void Turtle::reset() -{ - _diameter = 0.1; - - _fenceMode = false; - - +{ // put turtle at (0,0,0), head upwards, back towards camera _position.setXYZ(0.0, 0.0, 0.0); @@ -230,42 +250,15 @@ void Turtle::reset() _heading.setXYZ(0.0, 1.0, 0.0); _left.setXYZ(1.0, 0.0, 0.0); _up.setXYZ(0.0, 0.0, 1.0); -} - - - -/** - * Decrement diameter of segment - */ -void Turtle::decrementDiameter() -{ - // TODO: dynamic value... - _diameter *= 0.8; -} - - - -/** - * Begin creation of a filled surface - */ -void Turtle::fenceInBegin() -{ - _fenceMode = true; - _model->fillBegin(); - _model->point(_position.getX(), _position.getY(), _position.getZ()); -} - - - -/** - * End creation of a filled surface - */ -void Turtle::fenceInEnd() -{ - _model->fillEnd(); - _fenceMode = false; + // empty the stacks + _positionStack = stack(); + _headingStack = stack(); + _leftStack = stack(); + _upStack = stack(); + _diameterStack = stack(); + _colorIndexStack = stack(); } diff --git a/src/turtle.h b/src/turtle.h index d56c09a..c005d13 100644 --- a/src/turtle.h +++ b/src/turtle.h @@ -33,14 +33,14 @@ using namespace std; /** - * The model renderer + * The model creator */ class Turtle { public: /** * Constructor - * @param model render this model + * @param model create this model */ Turtle(Model *model); @@ -89,6 +89,11 @@ public: */ void walk(); + /** + * Walk forward, creating a filled surface + */ + void fillWalk(); + /** * Save current state to stack */ @@ -104,21 +109,6 @@ public: */ void reset(); - /** - * Decrement diameter of segment - */ - void decrementDiameter(); - - /** - * Begin creation of a filled surface - */ - void fenceInBegin(); - - /** - * End creation of a filled surface - */ - void fenceInEnd(); - /** * Set turn/pitch/roll angle * @param angle the angle, in radians @@ -133,23 +123,22 @@ public: protected: - Coordinate _position; // current position + Coordinate _position; // Current position - Vector _heading; // forward pointing vector - Vector _left; // left pointing vector - Vector _up; // up pointing vector + Vector _heading; // Forward pointing vector + Vector _left; // Left pointing vector + Vector _up; // Up pointing vector - double _angle; // turn/pitch/roll angle - double _diameter; // diameter of segment - bool _fenceMode; // create filled surface? + double _angle; // Turn/pitch/roll angle, in radians - stack _positionStack; // positions in stack - stack _headingStack; // heading vectors in stack - stack _leftStack; // left vectors in stack - stack _upStack; // up vectors in stack - stack _diameterStack; // diameters in stack + stack _positionStack; // Positions in stack + stack _headingStack; // Heading vectors in stack + stack _leftStack; // Left vectors in stack + stack _upStack; // Up vectors in stack + stack _diameterStack; // Diameters in stack + stack _colorIndexStack; // Colors indices in stack - Model *_model; // the rendered model + Model *_model; // The created model }; diff --git a/src/vector.cpp b/src/vector.cpp index 7b51842..3f68193 100644 --- a/src/vector.cpp +++ b/src/vector.cpp @@ -100,7 +100,7 @@ void Vector::normalize() /** - * Get scalar product of the vectors + * Get scalar product of two vectors * @param vector arbitrary vector * @return the scalar product */ @@ -116,7 +116,7 @@ double Vector::getScalarProduct(Vector vector) /** - * Get cross product of the vectors + * Get cross product of two vectors * @param vector arbitrary vector * @return the cross product */ @@ -132,7 +132,7 @@ Vector Vector::getCrossProduct(Vector vector) /** - * Get angle between the vectors + * Get angle between two vectors * @param vector the second (normalized) vector * @return the angle, in degrees */ diff --git a/src/vector.h b/src/vector.h index df1e758..438b325 100644 --- a/src/vector.h +++ b/src/vector.h @@ -58,21 +58,21 @@ public: void normalize(); /** - * Get scalar product of the vectors + * Get scalar product of two vectors * @param vector arbitrary vector * @return the scalar product */ double getScalarProduct(Vector vector); /** - * Get cross product of the vectors + * Get cross product of two vectors * @param vector arbitrary vector * @return the cross product */ Vector getCrossProduct(Vector vector); /** - * Get angle between the vectors + * Get angle between two vectors * @param vector the second (normalized) vector * @return the angle, in degrees */ diff --git a/src/xmlstructure.cpp b/src/xmlstructure.cpp index b7466c0..f2832c3 100644 --- a/src/xmlstructure.cpp +++ b/src/xmlstructure.cpp @@ -42,7 +42,7 @@ XMLStructure::XMLStructure() _rootElement = NULL; _activeElement = NULL; _activeDocument = NULL; - _activeChildInList = NULL; + _activeChildInList = (xmlpp::Node::NodeList::iterator)NULL; } -- 2.34.1