00001 #ifndef __LSYSTEM_H
00002 #define __LSYSTEM_H
00003
00004
00005 #include <boost/algorithm/string.hpp>
00006 #include <string>
00007 #include <list>
00008 #include "image.h"
00009 #include "image_draw.h"
00010
00011 namespace mimas {
00012
00021 class lsystem: public object
00022 {
00023 public:
00024 void setLstring(std::string str);
00025 std::string getLstring();
00026 void setAxiom(std::string str);
00027 void setRule(std::string rule);
00028 void setAngleStep(int val);
00029 void iterate(int numIterations=1);
00030 void setLineLength(double val);
00031 template<typename T>void drawLsystem(image<T> &image, int startx, int starty, T colour);
00032 lsystem();
00033
00034 private:
00035 std::string lstring, axiom, rule;
00036 int anglestep;
00037 double d;
00038 };
00039
00040
00041
00042 lsystem::lsystem()
00043 {
00044
00045
00046 setAxiom("F");
00047 setRule("FF-[-F+F+F]+[+F-F-F]");
00048 setLstring("++++F");
00049 setAngleStep(22);
00050 setLineLength(5.0);
00051 }
00052
00053
00054 void lsystem::setLstring(std::string str)
00055 {
00056 lstring=str;
00057 }
00058
00059
00060 std::string lsystem::getLstring()
00061 {
00062 return lstring;
00063 }
00064
00065
00066 void lsystem::setAxiom(std::string str)
00067 {
00068 axiom=str;
00069 }
00070
00071
00072 void lsystem::setRule(std::string str)
00073 {
00074 rule=str;
00075 }
00076
00077
00078
00079 void lsystem::setAngleStep(int val)
00080 {
00081 anglestep=val;
00082 }
00083
00084
00085 void lsystem::iterate(int numIterations)
00086 {
00087 if (numIterations<1) return;
00088
00089 for (int i=0; i<numIterations; i++)
00090 boost::replace_all(lstring,axiom,rule);
00091 }
00092
00093
00094 void lsystem::setLineLength(double val)
00095 {
00096
00097 d=val;
00098 }
00099
00100 template<typename T>
00101 void lsystem::drawLsystem(image<T> &image, int startx, int starty, T colour)
00102 {
00103 std::list<double> xlist;
00104 std::list<double> ylist;
00105 std::list<int> anglelist;
00106
00107 double x=(double)startx,y=(double)starty;
00108 int angle=0;
00109 double theta;
00110
00111 for (int i=0; i<(int)lstring.length(); i++)
00112 {
00113 double newx, newy;
00114 theta=M_PI*(double)angle/180.0;
00115 switch(lstring[i])
00116 {
00117 case 'F' :
00118 newx=(x+d*cos(theta));
00119 newy=(y-d*sin(theta));
00120 drawLine(image,(int)x,(int)y,(int)newx,(int)newy,colour);
00121 x=newx;
00122 y=newy;
00123 break;
00124 case '+' :
00125 angle+=anglestep;
00126 break;
00127 case '-' :
00128 angle-=anglestep;
00129 break;
00130 case '[':
00131 xlist.push_back(x);
00132 ylist.push_back(y);
00133 anglelist.push_back(angle);
00134 break;
00135 case ']':
00136 if (anglelist.size()>0)
00137 {
00138 x=xlist.back();
00139 y=ylist.back();
00140 angle=anglelist.back();
00141 xlist.pop_back();
00142 ylist.pop_back();
00143 anglelist.pop_back();
00144 }
00145 break;
00146 default:
00147 break;
00148 }
00149
00150 }
00151
00152 }
00153
00155
00156 };
00157
00158
00159 #endif