introduction  —  namespaces  —  modules  —  classes  —  files  —  globals  —  members  —  examples  —  Marc Toussaint

std.h

Go to the documentation of this file.
00001 /*  Copyright (C) 2000, 2006  Marc Toussaint.
00002     email: mtoussai@inf.ed.ac.uk
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Lesser General Public
00006     License as published by the Free Software Foundation; either
00007     version 2.1 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Lesser General Public License for more details.
00013 
00014     A copy of the GNU Lesser General Public License can usually be found
00015     at http://www.gnu.org/copyleft/lesser.html; if not, write to the Free
00016     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00017     02110-1301 USA */
00018 
00022 #ifndef MT_std_h
00023 #define MT_std_h
00024 
00025 
00026 //--------- standard includes:
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <fstream>
00030 #include <sstream>
00031 #include <math.h>
00032 #include <vector>
00033 #include <typeinfo>
00034 #if defined MT_MSVC // || defined WIN32 || defined _WIN32 || defined _MSC_VER
00035 #  include<limits>
00036 #  include<time.h>
00037 #  include<sys/timeb.h> 
00038 #  define MT_TIMEB
00039 #  ifdef MT_QT
00040 #    include<windows.h>
00041 #    undef min //I hate it that windows defines these macros!
00042 #    undef max
00043 #    undef  NOUNICODE
00044 #    define NOUNICODE
00045 //#    define QT_DLL
00046 //#    define _MSC_VER 1300
00047 //#    define _GDI32_
00048 //#    define _MBCS
00049 //#    define QT_THREAD_SUPPORT
00050 #  endif
00051 #  pragma warning(disable: 4305 4244 4250 4355 4786)
00052 #endif
00053 #if defined MT_MinGW
00054 #  include<unistd.h>
00055 #  include<sys/time.h>
00056 #  include<sys/timeb.h>
00057 #  define MT_TIMEB
00058 #endif
00059 #if defined MT_Linux || defined MT_Cygwin
00060 #  include<unistd.h>
00061 #  include<sys/time.h>
00062 #  include<sys/times.h>
00063 #  include<sys/resource.h>
00064 #endif
00065 
00066 #ifdef MT_doxy
00067 #  define DOX !\brief
00068 #endif
00069 
00070 //--------- my namespace:
00072 namespace MT{
00073   inline int debugBreakpoint(){
00074     char c; c=0;
00075     //std::cout <<"HALT breakpoint..." <<std::endl; std::cin.getline(&c,1); //force to wait
00076     return 0; //insert a break point here, if you want...
00077   }
00078 }
00079 
00080 
00081 //--------- error handling:
00082 #ifndef HALT
00083 #  define MT_MSG(msg) { std::cerr <<__FILE__ <<':' <<__LINE__ <<": " <<msg <<std::endl; }
00084 #  define HALT(msg) { std::cerr <<"HALT:" <<__FILE__ <<':' <<__LINE__\
00085                       <<":\n --- "<<msg<<" --- "<<std::endl; MT::debugBreakpoint(); abort();}
00086 #endif
00087 
00088 
00089 //--------- check macros:
00090 #ifndef MT_NOCHECK
00091 #  define CHECK(cond,msg) if(!(cond)) HALT("CHECK failed: "<<msg);
00092 #else
00093 #  define CHECK(cond,msg)
00094 #endif
00095 
00096 
00097 //--------- basic defs:
00098 #define MT_PI 3.14159265358979323846
00099 //#define MT_2PI (2.*3.14159265358979323846)
00100 #define MT_LN2 0.69314718055994528622676398299518041312694549560546875
00101 #define MT_2PI 6.283195307179587
00102 #define MT_LnSqrt2Pi -0.9189385332046727417803296 
00103 #define MT_SQRT2 1.414213562373095049
00104 #define MT_SQRTPI 1.772453850905516027
00105 typedef unsigned char byte; 
00106 typedef unsigned int uint;  
00107 typedef void (*voidFct)();  
00108 
00109 
00110 //--------- macros for looping
00111 #ifndef forall
00112 #define forall(i,a)            for(a.First(i)              ;a.CheckNext(i);    a.Next(i))
00113 #define forall_rev(i,a)        for(a.Last(i)               ;a.CheckPrev(i);    a.Prev(i))
00114 #define forall_save(i,j,a)     for(a.First(i),j=i,a.Next(j);a.CheckNext(i);i=j,a.Next(j))
00115 #define forall_rev_save(i,j,a) for(a.Last(i) ,j=i,a.Prev(j);a.CheckPrev(i);i=j,a.Prev(j))
00116 #endif
00117 
00118 
00119 //--------- macros to define the standard << and >> operatos for most my classes:
00120 #define stdInPipe(type)\
00121   inline std::istream& operator>>(std::istream& is,type& x){ x.read(is);return is; }
00122 #define stdEqPipe(type)\
00123   inline type& operator<<(type& x,const char* str){ std::istringstream ss(str); ss >>x; return x; }
00124 #define stdOutPipe(type)\
00125   inline std::ostream& operator<<(std::ostream& os,const type& x){ x.write(os); return os; }
00126 #define stdPipes(type)\
00127   inline std::istream& operator>>(std::istream& is,type& x){ x.read(is);return is; }\
00128   inline std::ostream& operator<<(std::ostream& os,const type& x){ x.write(os); return os; }
00129 
00130 
00131 #define fwdStdPipes(type)\
00132   inline std::istream& operator>>(std::istream& is,type& x);\
00133   inline std::ostream& operator<<(std::ostream& os,const type& x);
00134 
00135 
00136 //--------- macros for piping doubles EXACTLY (without rounding errors) in hex coding:
00137 #define OUTHEX(y) "0x" <<std::hex <<*((unsigned long*)&y) <<std::dec
00138 #define INHEX(y) std::hex >>*((unsigned long*)&y) >>std::dec
00139 
00140 
00141 
00142 //--------- standard conversion base type to a class:
00143 #ifndef MT_doxy
00144 
00145 template<class T>
00146 class basetype{
00147 public:
00148   T x; 
00149   basetype():x(){};
00150   basetype(const T _x):x(_x){};
00151 
00152   T& data(){ return x; }
00153   operator T() const{ return x; } 
00154   void read(std::istream& is){ is >>x; } 
00155   void write(std::ostream& os) const{ os <<x; } 
00156 };
00157 template<class T> stdInPipe(basetype<T>);
00158 template<class T> stdOutPipe(basetype<T>);
00159 
00160 namespace MT{
00161   typedef basetype<byte> Byte;
00162   typedef basetype<int> Int;
00163   typedef basetype<float> Float;
00164   typedef basetype<double> Double;
00165 }
00166 #endif
00167 
00168 //--------- tools to scan (parse) from a stream"
00169 namespace MT{
00170   inline char skip(std::istream&,char* skipchars=" \n\r\t"); //forward declaration..
00171   inline char peerFirstChar(std::istream& is){ char c; skip(is); is.get(c); is.putback(c); return c; }
00172 }
00174 inline std::istream& operator>>(std::istream& is,const char* str){
00175   uint i,n=strlen(str);
00176   char *buf=new char [n+1]; buf[n]=0;
00177   MT::skip(is," \n\r\t");
00178   is.read(buf,n);
00179   if(!is.good() || strcmp(str,buf)){
00180     for(i=n;i--;) is.putback(buf[i]);
00181     is.setstate(std::ios::failbit);
00182     std::cout <<"WARNING: scanning of constant string `" <<str
00183         <<"' failed! (read instead: `" <<buf <<"')" <<std::endl;
00184   }
00185   delete[] buf;
00186   return is;
00187 }
00189 inline std::istream& operator>>(std::istream& is,char* str){
00190   return is >>(const char*)str;
00191 }
00192 
00193 
00194 
00195 
00196 //===========================================================================
00197 //
00198 // what follows is somewhat messy organized:
00199 // standard methods for my namespace
00200 //
00201 
00202 namespace MT{
00203   extern int argc;
00204   extern char** argv;
00205   extern std::ifstream cfgFile;
00206   extern bool cfgOpenFlag;
00207   extern std::vector<void*> parameters;
00209   extern bool IOraw;
00211   extern bool noLog;
00212 
00214   std::ofstream& log(const char *name="MT.log");
00215 
00217   void open(std::ofstream& fs,const char *name,char* errmsg="");
00218 
00220   void open(std::ifstream& fs,const char *name,char* errmsg="");
00221 
00225   template<class T>
00226   void save(const T& x,const char *filename){
00227     std::ofstream file;
00228     MT::open(file,filename);
00229     file <<x;
00230     file.close();
00231   }
00232 
00236   template<class T>
00237   void load(T& x,const char *filename){
00238     std::ifstream file;
00239     MT::open(file,filename);
00240     file >>x;
00241     file.close();
00242   }
00243 
00245   inline bool contains(const char* s,char c){
00246     for(uint i=0;s[i];i++) if(s[i]==c) return true;
00247     return false;
00248   }
00249 
00251   inline char skip(std::istream& is,char* skipchars){
00252     char c;
00253     do{ c=is.get(); } while(contains(skipchars,c));
00254     is.putback(c);
00255     return c;
00256   }
00257 
00259   inline void skipLine(std::istream& is){
00260     char c;
00261     do{ c=is.get(); } while(c!='\n');
00262   }
00263 
00265   byte bit(byte *str,uint i);
00266 
00268   void flip(byte& b,uint i);
00269 
00271   void flip(int& b,uint i);
00272 
00275   double modMetric(double x,double y,double mod);
00276 
00278   double sign(double x);
00279 
00281   double linsig(double x);
00282 
00283   void constrain(float& x,float a,float b);
00284 
00286   float phi(float dx,float dy);
00287 
00290   inline double DIV(double x,double y,bool force=false){
00291     if(x==0.) return 0.;
00292     if(force){ if(y==0.) return 0.; }else CHECK(y!=0,"Division by Zero!");
00293     return x/y;
00294   }
00295 
00296   inline double sigmoid11(double x){ return x/(1.+::fabs(x)); }
00297 
00298   template<class T> T MIN(T a,T b){ return a<b?a:b; }
00299   template<class T> T MAX(T a,T b){ return a>b?a:b; }
00300 
00302   double approxExp(double x);
00303 
00305   double Log(double x);
00306 
00308   uint Log2(uint n);
00309 
00311   double sqr(double x);
00312 
00315   double realTime();
00316 
00319   double cpuTime();
00320 
00324   double sysTime();
00325 
00328   double totalTime();
00329   
00331   char *date();
00332 
00334   void wait(double sec);
00335 
00337   void wait();
00338 
00340   long mem();
00341 
00343   void resetTimer();
00344 
00346   double getTimer(bool reset=true);
00347 
00349   void init(int _argc, char *_argv[]);
00350 
00352   bool checkOption(const char *tag);
00353 
00355   bool getOption(const char *tag,char* &option);
00356 
00360   void openConfigFile(char* name=0);
00361 
00362 #ifdef MT_QT
00363 
00364   void initQt();
00365 #ifndef MT_doxy
00366 
00367   struct InitQt{ InitQt(){ initQt(); } };
00368 #endif
00369 #else
00370   inline void initQt(){ MT_MSG("Warning: initQt without QT configured"); }
00371 #endif
00372 }
00373 
00374 
00375 
00376 //===========================================================================
00377 //
00378 // Parameter class - I use it frequently to read parameters from file or cmd line
00379 // 
00380 
00381 namespace MT{
00386   template<class type>
00387   class Parameter{
00388   public:
00389     const char* typeName;
00390     type value,Default;
00391     char* tag;
00392     bool initialized,hasDefault;
00393 
00394 
00395   public:
00397 
00399     Parameter(char* _tag){
00400       typeName=typeid(type).name();
00401       MT::parameters.push_back(this);
00402       initialized=false;
00403       tag=_tag;
00404       hasDefault=false;
00405     };
00406 
00409     Parameter(char* _tag,const type& _default){
00410       typeName=typeid(type).name();
00411       MT::parameters.push_back(this);
00412       initialized=false;
00413       tag=_tag;
00414       hasDefault=true;
00415       Default=_default;
00416     };
00417 
00418     ~Parameter(){
00419       std::vector<void*>::iterator it;
00420       for(it=MT::parameters.begin();it!=MT::parameters.end();it++)
00421   if(*it==this){ MT::parameters.erase(it); return; }
00422     }
00423 
00425 
00427     operator type(){ if(!initialized) initialize(); return value; }
00428 
00430     type& operator()(){ if(!initialized) initialize(); return value; }
00431 
00432 
00434 
00436     type& operator=(const type v){ initialized=true; value=v; return value; }
00437 
00439     void setTag(char* _tag){ tag=_tag; }
00440 
00444     void reInitialize(){ initialized=false; }
00445 
00446 
00448 
00452     bool grabFromCmdLine(){
00453       char* opt;
00454       if(!getOption(tag,opt)) return false;
00455       std::istringstream s(opt);
00456       s >>value;
00457       if(s.fail()) HALT("error when reading parameter from command line: " <<tag);
00458       return true;
00459     }
00460 
00464     bool grabFromCfgFile(){
00465       if(!cfgOpenFlag){
00466   log() <<"..." <<std::endl;
00467   openConfigFile();
00468   log() <<std::setw(40) <<"..." <<": " <<std::setw(5);
00469       }
00470       cfgFile.clear();
00471       cfgFile.seekg(std::ios::beg);
00472       if(!cfgFile.good()) return false;
00473 
00474       unsigned n=strlen(tag);
00475       char *buf=new char [n+2]; memset(buf,0,n+2);
00476       while(cfgFile.good()){
00477   memmove(buf,buf+1,n);
00478   buf[n]=cfgFile.get();
00479   if(buf[n]==' ' || buf[n]=='\t' || buf[n]==':' || buf[n]=='='){ buf[n]=0; if(!strcmp(tag,buf)) break; buf[n]=':'; }
00480       };
00481       delete[] buf;
00482 
00483       if(!cfgFile.good()) return false;
00484  
00485       skip(cfgFile," :=\n\r\t");
00486       cfgFile >>value;
00487  
00488       if(cfgFile.fail()) HALT("error when reading parameter " <<tag);
00489       return true;
00490     }
00492 
00493   private:
00494     void initialize(){
00495       if(!initialized){
00496   if(!cfgOpenFlag) openConfigFile();
00497   initialized=true;
00498   if(!tag) HALT("uninitialized parameter without tag!");
00499   log() <<std::setw(20) <<tag <<" = " <<std::setw(5);
00500   log().flush();
00501 
00502   if(grabFromCmdLine()){
00503     log() <<value <<" [" <<typeid(value).name() <<"] (cmd line!)" <<std::endl;
00504     return;
00505   }
00506 
00507   if(grabFromCfgFile()){
00508     log() <<value <<" [" <<typeid(value).name() <<"]" <<std::endl;
00509     return;
00510   }
00511 
00512   if(hasDefault){
00513     value=Default;
00514     log() <<value <<" [" <<typeid(value).name() <<"] (default!)"<<std::endl;
00515     return;
00516   }
00517 
00518   HALT("could not initialize parameter `" <<tag
00519        <<"': parameter has no default;\n     either use command option `-"
00520        <<tag <<" ...' or specify `"
00521        <<tag <<"= ...' in the config file `MT.cfg'");
00522       }
00523     }
00524   };
00525 
00526 }
00527 
00528 
00529 
00530 //===========================================================================
00531 //
00532 // a very basic memory buffer
00533 //
00534 
00535 namespace MT{
00537 struct Mem{
00538   char *p; 
00539   uint N;  
00540   uint M;  
00541   uint S;  
00542   Mem(){ p=0; S=1; N=0; M=0; }
00543   Mem(uint SizeOf){ p=0; S=SizeOf; N=0; M=0; }
00544   ~Mem(){ if(M) delete[] p; }
00545   void resize(uint n,bool copy=true);
00546   char *append(){ resize(N+1); return get(N-1); }
00547   void free(){ if(M) delete[] p; p=0; M=N=0; }
00548   void zero(){ memset(p,0,S*M); }
00549   char *get(uint i) const{ CHECK(i<N,"Mem range error ("<<i<<"<"<<N<<")"); return p+S*i; }
00550   Mem& operator=(const Mem& m);
00551 };
00552 }
00553 
00554 //#define memget(M,i,T) *((T*)M.get(i))
00555 //#define memappend(M,T) *((T*)M.append())
00556 
00557 
00558 //===========================================================================
00559 //
00560 // random number generator
00561 //
00562 
00563 namespace MT{
00567   class Rnd{
00568   private:
00569     bool ready;
00570     int rpoint;     /* Feldindex    */
00571     long rfield[256];   /* Schieberegisterfeld  */
00572 
00573 
00574   public:
00576     Rnd(){ ready=false; };
00577 
00578 
00579   public:
00580 
00581     unsigned long seed(unsigned long n);
00582 
00584     unsigned long seed();
00585 
00587     unsigned long clockSeed();
00588 
00589   public:
00590 
00591     inline uint num(){ if(!ready) seed(); return (uint)rnd250() >> 5; }
00593     inline uint operator ()(){ return num(); }
00595     inline uint num(uint limit){
00596       CHECK(limit,"zero limit in rnd.num()"); return num() % limit; }
00597     inline uint num(int lo,int hi){ return lo+num(hi-lo+1); }
00599     inline uint operator ()(uint i){ return num(i); }
00600     inline uint operator ()(int lo,int hi){ return num(lo,hi); }
00602     inline double uni(){ return ((double)num(1<<22))/(1<<22); }
00604     inline double uni(double low,double high){ return low+uni()*(high-low); }
00606     double gauss(double stdDev);
00610     uint poisson(double mean);
00612 
00613 
00614   private:
00615     inline long  rnd250(){
00616       rpoint = (rpoint+1) & 255;          // Index erhoehen
00617       return rfield[rpoint] =  rfield[(rpoint-250) & 255]
00618                        ^ rfield[(rpoint-103) & 255];
00619     }
00620 
00621     void seed250(long seed);
00622   };
00623 
00625   extern Rnd rnd;
00626 }
00627 
00628 
00629 
00630 //===========================================================================
00631 //
00632 // string class
00633 //
00634 
00635 namespace MT{
00636   typedef std::iostream IOStream;
00637   
00644   class String:public IOStream{
00645   private:
00646     class StringBuf:public std::streambuf{
00647     public:
00648       Mem mem;
00649       const char* ptr() const{ return mem.p; }
00650       char* ptr(){ return mem.p; }
00651       virtual int overflow(int C = EOF){
00652   *mem.get(mem.N-1)=C; *mem.append()=0; resetI();
00653   return C;
00654       }
00655       void resetI(){ setg(ptr(),ptr(),ptr()+mem.N-1); }
00656       char *getIpos(){ return gptr(); }
00657       void setIpos(char* p){
00658   setg(ptr(),p,ptr()+mem.N-1);
00659       }
00660     };
00661     
00662   public:
00663     StringBuf buf;
00665     String():IOStream(&buf){ clr(); }
00667     String(const String& s):IOStream(&buf){ this->operator=(s); }
00669     String(const char* s):IOStream(&buf){ this->operator=(s); }
00671     IOStream& str(){ return (IOStream&)(*this); }
00674     operator char*(){ return buf.ptr(); }
00676     operator const char*() const{ return buf.ptr(); }
00678     char* ptr(){ return buf.ptr(); }
00680     char operator()(uint i){ return *buf.mem.get(i); }
00682     void operator=(const String& s){ buf.mem=s.buf.mem; buf.resetI(); }
00684     void operator=(const char *s){ buf.mem.resize(strlen(s)+1); memmove(buf.ptr(),s,strlen(s)+1); buf.resetI(); }
00686     bool operator==(const char *s){ return !strcmp(buf.ptr(),s); }
00688     bool operator==(const String& s){ return !strcmp(buf.ptr(),s.buf.ptr()); }
00690     String& clr(){ buf.mem.resize(1); *buf.mem.get(0)=0; clear(); return *this; }
00694     String& resetI(){ buf.resetI(); clear(); return *this; }
00695     char *getIpos(){ return buf.getIpos(); }
00696     void setIpos(char* p){buf.setIpos(p); }
00697     
00699     uint N() const{ return buf.mem.N-1; }
00702     template<class T>
00703     String operator+(const T& v) const{
00704       String news(*this); news <<v; return news;
00705     }
00707     void write(std::ostream& os) const{ os <<buf.ptr(); }
00710     void read(std::istream& is,char *stopSymbols="\n\r"){
00711       buf.mem.resize(0);
00712       char c=is.get();
00713       while(is.good() && !MT::contains(stopSymbols,c)){
00714   *buf.mem.append()=c; c=is.get(); }
00715       is.putback(c);
00716       is.clear();
00717       *buf.mem.append()=0;
00718       resetI();
00719     }
00720   };
00721 }
00722 stdPipes(MT::String);
00723 
00724 #define STRING(x) ((MT::String&)(MT::String().str()<<x)).ptr()
00725 
00726 
00727 
00728 //===========================================================================
00729 //
00730 // color class
00731 //
00732 
00733 #ifndef MT_doxy
00734 namespace MT{
00736   class Color{
00737   public:
00738     float
00739       r, 
00740       g, 
00741       b; 
00742     
00744     friend inline Color operator+(const Color& c1,const Color& c2){
00745       return Color(c1.r+c2.r, c1.g+c2.g, c1.b+c2.b); }
00746     
00748     friend inline Color operator*(float f,const Color& c2){
00749       return Color(f*c2.r, f*c2.g, f*c2.b); }
00750     
00751   public:
00753     Color(){ setGray(1.); }
00754     
00756     Color(float red,float green,float blue){ setRgb(red,green,blue); }
00757     
00759     Color& operator=(const Color& c){ r=c.r; g=c.g; b=c.b; return *this; }
00760     
00762     bool operator!(){ if(r==0. && g==0. && b==0.) return true; return false; }
00763     
00765     operator const float*() const{ return (float*)this; }
00766     
00768     void setIndex(unsigned i){
00769       if(!i) setRgb(0.,0.,0.); else setHsv(((i-1)*63)%360,255,255); }
00770     
00772     void setRgb(float red,float green,float blue){ r=red; g=green; b=blue; }
00773     
00775     void setRgbByte(byte red,byte green,byte blue){
00776       r=red/255.f; g=green/255.f; b=blue/255.f; }
00777     
00779     void setHsv(int hue,byte sat,byte val){
00780       float h=hue/60.f,s=sat/255.f,v=val/255.f;
00781       h=(float)fmod(h,6.f);
00782       r=g=b=0.;
00783       if(h<=1.)        { r=v; g=v*h; }
00784       if(h>1. && h<=2.){ g=v; r=v*(2.f-h); }
00785       if(h>2. && h<=3.){ g=v; b=v*(h-2.f); }
00786       if(h>3. && h<=4.){ b=v; g=v*(4.f-h); }
00787       if(h>4. && h<=5.){ b=v; r=v*(h-4.f); }
00788       if(h>5. && h<=6.){ r=v; b=v*(6.f-h); }
00789       r=s*r+(1.f-s)*v;
00790       g=s*g+(1.f-s)*v;
00791       b=s*b+(1.f-s)*v;
00792     }
00793     
00795     void setTemp(float temp){
00796       Color hot(1.,0.,0.),middle(1.,1.,0.),cold(0.,0.,1.);
00797       if(temp>1.) temp=1.;
00798       if(temp<0.) temp=0.;
00799       if(temp>.5){ temp=2.f*temp-1.f; *this=temp*hot + (1.-temp)*middle; }
00800       else{ temp=2.f*temp; *this=temp*middle + (1.f-temp)*cold; }
00801     }
00802     
00804     void setTemp2(float temp){
00805       Color r(1.,0.,0.),y(1.,1.,0.),zero(.5,.5,.5),g(0.,1.,0.),b(0.,0.,1.);
00806       if(temp>1.) temp=1.;
00807       if(temp<-1.) temp=-1.;
00808       if(temp>.5){  temp=2.*temp-1.; *this=temp*r + (1.-temp)*y; return; }
00809       if(temp>.0){  temp=2.*temp;    *this=temp*y + (1.-temp)*zero; return; }
00810       if(temp>-.5){ temp=-2.*temp;   *this=temp*g + (1.-temp)*zero; return; }
00811       { temp=-2.*temp-1.;*this=temp*b + (1.-temp)*g; return; }
00812     }
00813     
00815     void setGray(float gray){ if(gray<0) gray=0.; if(gray>1) gray=1.; r=g=b=gray; }
00816     
00818     void getRgb(byte& R,byte& G,byte& B) const{
00819       R=(byte)(255.*r); G=(byte)(255.*g); B=(byte)(255.*b); }
00820     
00822     float getGray() const{ return (r+g+b)/3.; }
00823     
00825     void whiten(float f){
00826       if(f>1.) f=1.; else if(f<0.) f=0.;
00827       r+=f*(1.-r); g+=f*(1.-g); b+=f*(1.-b);
00828     }
00829     
00831     void blacken(float f){
00832       if(f>1.) f=1.; else if(f<0.) f=0.;
00833       r-=f*r; g-=f*g; b-=f*b;
00834     }
00835     
00837     void mix(Color& A,Color& B,float f=.5){
00838       if(f>1.) f=1.; else if(f<0.) f=0.;
00839       r=f*A.r+(1.-f)*B.r;
00840       g=f*A.g+(1.-f)*B.g;
00841       b=f*A.b+(1.-f)*B.b;
00842     }
00843     
00845     void mixAdd(Color& A,Color& B,float f=.5){
00846       if(f>1.) f=1.; else if(f<0.) f=0.;
00847       r=1.-f*(1.-A.r)+(1.-f)*(1.-B.r);
00848       g=1.-f*(1.-A.g)+(1.-f)*(1.-B.g);
00849       b=1.-f*(1.-A.b)+(1.-f)*(1.-B.b);
00850     }
00851     
00853     void mixSub(Color& A,Color& B,float f=.5){
00854       if(f>1.) f=1.; else if(f<0.) f=0.;
00855       r=1.-::pow(1.f-A.r,f)*::pow(1.f-B.r,1.f-f);
00856       g=1.-::pow(1.f-A.g,f)*::pow(1.f-B.g,1.f-f);
00857       b=1.-::pow(1.f-A.b,f)*::pow(1.f-B.b,1.f-f);
00858     }
00859     
00861     void min(Color& A,Color& B){
00862       r=A.r<B.r?A.r:B.r;
00863       g=A.g<B.g?A.g:B.g;
00864       b=A.b<B.b?A.b:B.b;
00865     }
00866 
00868     void write(std::ostream& os) const{ os <<"(" <<r <<":" <<g <<":" <<b <<")"; }
00869     
00871     void read(std::istream& is){ is >>"(" >>r >>":" >>g >>":" >>b >>")"; }
00872   };
00873 }
00874 stdPipes(MT::Color);
00875 #endif
00876 
00877 
00878 //===========================================================================
00879 //
00880 // gnuplot calls
00881 //
00882 
00883 void gnuplot(const char* command);
00884 void gnuplotEPS(const char* file,const char* command);
00885 
00886 
00887 //===========================================================================
00888 //
00889 // implementations
00890 //
00891 
00892 #ifdef MT_IMPLEMENTATION
00893 #  include"std.cpp"
00894 #endif
00895 
00896 
00897 
00898 //===========================================================================
00899 //
00900 // USING's
00901 //
00902 
00903 using std::cout;
00904 using std::endl;
00905 using std::ofstream;
00906 using std::ifstream;
00907 using MT::rnd;
00908 using MT::Color;
00909 using MT::Parameter;
00910 using MT::String;
00911 
00912 
00913 #endif
[]