*** empty log message ***
authorspixx <spixx>
Sat, 4 Nov 2006 19:30:01 +0000 (19:30 +0000)
committerspixx <spixx>
Sat, 4 Nov 2006 19:30:01 +0000 (19:30 +0000)
16 files changed:
src/Makefile.am
src/coordinate.cpp
src/coordinate.h
src/lindenmayersystem.cpp
src/lindenmayersystem.h
src/lsystem.cpp
src/lsystem.xml
src/lsystemparameters.cpp
src/lsystemparameters.h
src/model.cpp
src/model.h
src/turtle.cpp
src/turtle.h
src/vector.cpp
src/vector.h
src/xmlstructure.cpp

index 909976e1800cac32b57e6892ee2bba680411f635..ed9bc07e5d1b1c6a87312e8590410b7b68f5c37c 100644 (file)
@@ -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
index 026addb05df119112436674d20a18cafab1087a5..ffef1c7e0a4b0b37da4bac378d8c5a5d6aac14bd 100644 (file)
@@ -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;
-}
index cac2a1a5e5fc9f119bea689af40b8187db601243..70c990a6e651b503090b2d176269fdb131278fbb 100644 (file)
@@ -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:
     
index 9a660233f29d9043f846c80a00b5ae83e78165a3..a4016346ae49b4664c44f3fd9aaf91375fcb23df 100644 (file)
 #include <cmath>
 
 #include <map>
-#include <iostream>
 #include <string>
 
 #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];
         }
     }
     
index efadab9a31aa785c94ae1350faec03008159feec..d71fde6b6530225b9fb471a26a40768ffbe400ad 100644 (file)
@@ -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<string,string> _rules;      // TODO: use unsorted container?
+    map<string,string> _rules;  // TODO: use unsorted container?
     int _numIterations;
     
-    Model *_model;      // The model for generation
+    Model *_model;      // The active model
     Turtle *_turtle;    // The rendering turtle
 };
 
index 27e51d37978f5a4e72b35d1a8e6a9c3207b4207a..cb9b2ca639582ebc980a701c9dee8f8ed02c5326 100644 (file)
 
 #include <cstdlib>
 
-#include <GL/freeglut.h>
-
-#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;
index 803a80983a8c6a5d0779200008ae25382a2d08af..6c832899c98c9e31da64c02d9a1949bfc334e721 100644 (file)
@@ -1,7 +1,13 @@
 <?xml version="1.0"?>
 <lsystem>
-  <axiom>A</axiom>
-  <rule name="A">A/[!+A&amp;A]/A</rule>
-  <angle>30.0</angle>
-  <iterations>4</iterations>
+  <axiom>P</axiom>
+  <rule name="E">FF</rule>
+  <rule name="I">FS[//&amp;&amp;L][//^^L]FS!</rule>
+  <rule name="L">[`{-f+ff+f-|-f+ff+f}]</rule>
+  <rule name="O">[&amp;&amp;&amp;E'/W////W////W////W////W]</rule>
+  <rule name="P">I+[P+O]--//[--L]I[++L]-[PO]++PO</rule>
+  <rule name="S">SFS</rule>
+  <rule name="W">['^F][{&amp;&amp;&amp;&amp;-f+f|-f+f}]</rule>
+  <angle>18.0</angle>
+  <iterations>6</iterations>
 </lsystem>
index c12e9e3ecaa7583a2427a612b03c5550166ee81b..bdd16eb000e3d619781860d5fc1fdc1b62c4e295 100644 (file)
@@ -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;
     }
 }
index 1d80635bad8e7f7896874fd2765493d2efbe0d24..e09bb457d7b23e395596af27151d2a650086f70d 100644 (file)
@@ -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);
index 48308a0cc39cc5d40c0a90796a58ce8e7fb7202b..9a8554b8dfa0494194c782cffcaf89a07e379c92 100644 (file)
 
 
 
+#include <vector>
+
 #include "GL/gl.h"
 #include "GL/glu.h"
 
+#include "color.h"
 #include "model.h"
 #include "vector.h"
 
  */
 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;
 }
index d7ebf26c2b20f63de244e9242824e9de7124e53d..a05d8e3edc3296ea434b04d3ffc44599b75b2def 100644 (file)
 #ifndef MODEL_H
 #define MODEL_H
 
+#include <vector>
+
 #include <GL/gl.h>
 
+#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<Color> _colorTable;  // Color table
+    int _colorIndex;            // Current index to color table
+    double _diameter;           // Current diameter of segment
+    double _diameterFactor;     // Diameter factor // TODO: "Diameter factor"?
 };
 
 
index 9847b5af8d8562e2f7f6a763a8f6694f8c774f31..69421c86433bb861191a8d82b313d69fc35462ca 100644 (file)
 #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<Coordinate>();
+    _headingStack = stack<Vector>();
+    _leftStack = stack<Vector>();
+    _upStack = stack<Vector>();
+    _diameterStack = stack<double>();
+    _colorIndexStack = stack<int>();
 }
 
 
index d56c09a371acd848cd19990bcb3ae8204d3f5ef6..c005d13b2a2b9cd734a15cdd5614696c546d7d5b 100644 (file)
@@ -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<Coordinate> _positionStack;       // positions in stack
-    stack<Vector> _headingStack;            // heading vectors in stack
-    stack<Vector> _leftStack;               // left vectors in stack
-    stack<Vector> _upStack;                 // up vectors in stack
-    stack<double> _diameterStack;           // diameters in stack
+    stack<Coordinate> _positionStack;       // Positions in stack
+    stack<Vector> _headingStack;            // Heading vectors in stack
+    stack<Vector> _leftStack;               // Left vectors in stack
+    stack<Vector> _upStack;                 // Up vectors in stack
+    stack<double> _diameterStack;           // Diameters in stack
+    stack<int> _colorIndexStack;            // Colors indices in stack
     
-    Model *_model;    // the rendered model
+    Model *_model;    // The created model
 };
 
 
index 7b518421adf90f30f8c1ddfeef2b50bfb7f533d8..3f68193c792231132f36c598280dee015537e8cf 100644 (file)
@@ -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
  */
index df1e758c23aafe93f53861edd550a4337de9e53a..438b3258f485ebe1936eb248d863e00273b31a2f 100644 (file)
@@ -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
      */
index b7466c0c560278ededb44427e6280a34846ce0da..f2832c3a86f02ca19150cb01be944ab4a1618a81 100644 (file)
@@ -42,7 +42,7 @@ XMLStructure::XMLStructure()
     _rootElement = NULL;
     _activeElement = NULL;
     _activeDocument = NULL;
-    _activeChildInList = NULL;
+    _activeChildInList = (xmlpp::Node::NodeList::iterator)NULL;
 }