Imported Upstream version 2~rc2+svn363
authorDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Thu, 15 Mar 2012 13:22:39 +0000 (15:22 +0200)
committerDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Thu, 15 Mar 2012 13:22:39 +0000 (15:22 +0200)
21 files changed:
CMakeLists.txt
examples/fltk_example.cpp
examples/full_test.cpp
examples/qt_example.cpp
include/mgl/canvas_cf.h
include/mgl/define.h
include/mgl/mgl.h
include/mgl/window.h
src/axis.cpp
src/canvas.cpp
src/canvas_cf.cpp
src/exec.cpp
src/pixel.cpp
texinfo/core_en.texi
texinfo/example_en.texi
texinfo/widget_en.texi
todo.txt
utils/mglview.cpp
widgets/fltk.cpp
widgets/qt.cpp
widgets/window.cpp

index 9f1c281df42b8a8c9f3fc74bfba262d0b6ca6a00..01a9fee1d9acfce584253f070d484560feb75fbd 100644 (file)
@@ -307,9 +307,9 @@ endif(NOT WIN32)
 add_subdirectory( src )
 add_subdirectory( widgets )
 add_subdirectory( utils )
-add_subdirectory( examples )
 add_subdirectory( include )
 add_subdirectory( udav )
 #add_subdirectory( mgllab )
-add_subdirectory( texinfo )
 add_subdirectory( lang )
+add_subdirectory( examples )
+add_subdirectory( texinfo )
index 23da92a6be0a92e501c1b29cb191e563a22b3ade..9e5eb5152b7cf2884314e330790dcd4953744bf2 100644 (file)
@@ -59,12 +59,12 @@ int main(int argc,char **argv)
        else    printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");\r
        switch(key)\r
        {\r
-               case '1':       gr = new mglWindow(0,sample_1,"1D plots");      break;\r
-               case '2':       gr = new mglWindow(0,sample_2,"2D plots");      break;\r
-               case '3':       gr = new mglWindow(0,sample_3,"3D plots");      break;\r
-               case 'd':       gr = new mglWindow(0,sample_d,"Dual plots");break;\r
-               case 't':       gr = new mglWindow(0,test_wnd,"Testing");       break;\r
-               default:        gr = new mglWindow(0,sample,"Drop and waves");  break;\r
+               case '1':       gr = new mglWindow(sample_1,"1D plots",0);      break;\r
+               case '2':       gr = new mglWindow(sample_2,"2D plots",0);      break;\r
+               case '3':       gr = new mglWindow(sample_3,"3D plots",0);      break;\r
+               case 'd':       gr = new mglWindow(sample_d,"Dual plots",0);break;\r
+               case 't':       gr = new mglWindow(test_wnd,"Testing",0);       break;\r
+               default:        gr = new mglWindow(sample,"Drop and waves",0);  break;\r
        }\r
        gr->Run();      return 0;\r
 #endif\r
index 385ee8821fa0f4cd4f4ce7274b99b9589534732b..109564b150bf94c58bcd28cba4b7211dae90bbaf 100644 (file)
@@ -38,8 +38,8 @@ void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);
 //-----------------------------------------------------------------------------\r
 int type = 0;\r
 int dotest  = 0;\r
-int width  = 1000;\r
-int height = 750;\r
+int width  = 800;\r
+int height = 600;\r
 int mini = 0;\r
 int big  = 0;\r
 int srnd = 0;\r
@@ -49,28 +49,42 @@ void smgl_combined(mglGraph *gr);
 void save(mglGraph *gr,const char *name,const char *suf);\r
 void test(mglGraph *gr)\r
 {\r
-       float q[] = {0,1,2,3, 4,5,6,7, 0,2,4,6, 1,3,5,7, 0,4,1,5, 2,6,3,7};\r
-       float xc[] = {-1,1,-1,1,-1,1,-1,1}, yc[] = {-1,-1,1,1,-1,-1,1,1}, zc[] = {-1,-1,-1,-1,1,1,1,1};\r
-       mglData qq(6,4,q), xx(8,xc), yy(8,yc), zz(8,zc);\r
-       gr->Light(true);        //gr->Alpha(true);\r
-       gr->SubPlot(2,1,0);     gr->Title("QuadPlot sample");   gr->Rotate(50,60);\r
-       gr->QuadPlot(qq,xx,yy,zz,"yr");\r
-       gr->QuadPlot(qq,xx,yy,zz,"k#");\r
-\r
-       float t[] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};\r
-       float xt[] = {-1,1,0,0}, yt[] = {-1,-1,1,0}, zt[] = {-1,-1,-1,1};\r
-       mglData tt(4,3,t), uu(4,xt), vv(4,yt), ww(4,zt);\r
-       gr->SubPlot(2,1,1);     gr->Title("TriPlot_sample");    gr->Rotate(50,60);\r
-       gr->TriPlot(tt,uu,vv,ww,"b");\r
-       gr->TriPlot(tt,uu,vv,ww,"k#");\r
-\r
-       gr->WriteXYZ("test.xyz");\r
-       gr->WriteSTL("test.stl");\r
-       gr->WriteOFF("test.off");\r
-       gr->WriteTEX("test.tex");\r
-       gr->WriteOBJ("test.obj");\r
-       gr->WriteOBJ("test1.obj","",true);\r
-       return;\r
+       //double v [5] = {0.000001, 10.000001, 20.000001, 30.000001, 39.999999}, *vv, Value;\r
+       // ERROR ERROR ERROR\r
+       //-----------------------------------------------------------------\r
+       double v [5] = {0.0, 10.0, 20.0, 30.0, 40.0}, *vv, Value;\r
+       //-----------------------------------------------------------------\r
+       double x [4] = {0, 10, 20, 30}, *xx;\r
+       double y [5] = {0, 10, 20, 30, 40}, *yy;\r
+       int\r
+       iy,ix,iz;\r
+       mglData Z(4,5), V(6), X(5), Y(4);\r
+       for (ix=0;ix<4;ix++){\r
+               for (iy=0;iy<5;iy++) {\r
+                       Z.Put(iy*10,ix,iy);\r
+               }\r
+       }\r
+       Z.Save ("A.txt");\r
+       vv = &v[0];\r
+       V.Set(vv, 5);\r
+       V.Save ("V.txt");\r
+       xx = &x[0];\r
+       X.Set(xx, 4);\r
+       yy = &y[0];\r
+       Y.Set(yy, 5);\r
+       gr->DefaultPlotParam();\r
+       gr->InPlot(0.0, 0.7, 0.0, 1.0);\r
+       gr->SetRanges(0,30,-5,45,-80,70);\r
+//     gr->Axis(mglPoint(0,-5),mglPoint(30,45));\r
+       gr->SetTicks('x', 5, 4); // sets tick step to 5\r
+       gr->SetTicks('y', 5, 4); // and draws 4 subticks\r
+       gr->Axis("xy");\r
+       gr->Box();\r
+       gr->Colorbar();\r
+       gr->Dens(X,Y,Z);\r
+       // Color Gradient\r
+       gr->Cont(V,X,Y,Z,"tk");\r
+       // Without Color        ERROR ERROR ERROR\r
 \r
        mglParse par;\r
        par.AllowSetSize(true);\r
@@ -335,7 +349,8 @@ void smgl_text(mglGraph *gr)        // text drawing
        if(mini)        return;\r
 \r
        gr->SubPlot(2,2,1,"");\r
-       gr->Puts(mglPoint(0), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", "@", -4);\r
+       gr->Puts(mglPoint(0,0.5), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", "@", -4);\r
+       gr->Puts(mglPoint(0,-0.5),"Text can be printed\non several lines");\r
 \r
        gr->SubPlot(2,2,2,"");\r
        mglData y;      mgls_prepare1d(&y);\r
@@ -1473,29 +1488,29 @@ void smgl_axis(mglGraph *gr)
 }\r
 //-----------------------------------------------------------------------------\r
 const char *mmgl_ticks="subplot 3 2 0:title 'Usual axis':axis\n"\r
-"subplot 3 2 2:title 'Too big/small range':ranges -1000 1000 0 0.001:axis\n"\r
+"subplot 3 2 1:title 'Too big/small range':ranges -1000 1000 0 0.001:axis\n"\r
 "subplot 3 2 3:title 'Too narrow range':ranges 100 100.1 10 10.01:axis\n"\r
 "subplot 3 2 4:title 'Disable ticks tuning':tuneticks off:axis\n"\r
-"subplot 3 2 1:title 'Manual ticks':ranges -pi pi 0 2:\nxtick -pi '\\pi' -pi/2 '-\\pi/2' 0 '0' 0.886 'x^*' pi/2 '\\pi/2' pi 'pi':axis\n"\r
+"subplot 3 2 2:title 'Manual ticks':ranges -pi pi 0 2:\nxtick -pi '\\pi' -pi/2 '-\\pi/2' 0 '0' 0.886 'x^*' pi/2 '\\pi/2' pi 'pi':axis\n"\r
 "# or you can use: list v -pi -pi/2 0 0.886 pi/2 pi:xtick v '-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi':axis\n"\r
 "subplot 3 2 5:title 'Time ticks':xrange 0 3e5:ticktime 'x':axis\n";\r
 void smgl_ticks(mglGraph *gr)\r
 {\r
        gr->SubPlot(3,2,0);     gr->Title("Usual axis");        gr->Axis();\r
-       gr->SubPlot(3,2,2);     gr->Title("Too big/small range");\r
+       gr->SubPlot(3,2,1);     gr->Title("Too big/small range");\r
        gr->SetRanges(-1000,1000,0,0.001);      gr->Axis();\r
        gr->SubPlot(3,2,3);     gr->Title("Too narrow range");\r
        gr->SetRanges(100,100.1,10,10.01);      gr->Axis();\r
        gr->SubPlot(3,2,4);     gr->Title("Disable ticks tuning");\r
-       gr->SetTuneTicks(false);        gr->Axis();\r
+       gr->SetTuneTicks(0);    gr->Axis();\r
 \r
-       gr->SubPlot(3,2,1);     gr->Title("Manual ticks");      gr->SetRanges(-M_PI,M_PI, 0, 2);\r
+       gr->SubPlot(3,2,2);     gr->Title("Manual ticks");      gr->SetRanges(-M_PI,M_PI, 0, 2);\r
        float val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};\r
        gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");\r
        gr->Axis();     gr->Grid();     gr->FPlot("2*cos(x^2)^2", "r2");\r
 \r
        gr->SubPlot(3,2,5);     gr->Title("Time ticks");        gr->SetRange('x',0,3e5);\r
-       gr->SetTickTime('x',0); gr->Axis();\r
+       gr->SetTicksTime('x',0);        gr->Axis();\r
 }\r
 //-----------------------------------------------------------------------------\r
 const char *mmgl_box="subplot 2 2 0:title 'Box (default)':rotate 50 60:box\n"\r
@@ -1513,7 +1528,7 @@ void smgl_box(mglGraph *gr)
 const char *mmgl_loglog="subplot 2 2 0 '<_':title 'Semi-log axis':ranges 0.01 100 -1 1:axis 'lg(x)' ''\n"\r
 "axis:fplot 'sin(1/x)':xlabel 'x':ylabel 'y = sin 1/x'\n"\r
 "subplot 2 2 1 '<_':title 'Log-log axis':ranges 0.01 100 0.1 100:axis 'lg(x)' 'lg(y)'\n"\r
-"axis:fplot 'sqrt(1+x^2)':xlabel 'x':ylabel 'y = \\sqrt{1+x^2}'\n"\r
+"axis:grid 'xy' 'g':fplot 'sqrt(1+x^2)':xlabel 'x':ylabel 'y = \\sqrt{1+x^2}'\n"\r
 "subplot 2 2 2 '<_':title 'Minus-log axis':ranges -100 -0.01 -100 -0.1:axis '-lg(-x)' '-lg(-y)'\n"\r
 "axis:fplot '-sqrt(1+x^2)':xlabel 'x':ylabel 'y = -\\sqrt{1+x^2}'\n"\r
 "subplot 2 2 3 '<_':title 'Log-ticks':ranges 0.01 100 0 100:axis 'sqrt(x)' ''\n"\r
@@ -1521,7 +1536,7 @@ const char *mmgl_loglog="subplot 2 2 0 '<_':title 'Semi-log axis':ranges 0.01 10
 void smgl_loglog(mglGraph *gr) // log-log axis\r
 {\r
        gr->SubPlot(2,2,0,"<_");        gr->Title("Semi-log axis");     gr->SetRanges(0.01,100,-1,1);   gr->SetFunc("lg(x)","");\r
-       gr->Axis();     gr->FPlot("sin(1/x)");  gr->Label('x',"x",0); gr->Label('y', "y = sin 1/x",0);\r
+       gr->Axis();     gr->Grid("xy","g");     gr->FPlot("sin(1/x)");  gr->Label('x',"x",0); gr->Label('y', "y = sin 1/x",0);\r
        gr->SubPlot(2,2,1,"<_");        gr->Title("Log-log axis");      gr->SetRanges(0.01,100,0.1,100);        gr->SetFunc("lg(x)","lg(y)");\r
        gr->Axis();     gr->FPlot("sqrt(1+x^2)");       gr->Label('x',"x",0); gr->Label('y', "y = \\sqrt{1+x^2}",0);\r
        gr->SubPlot(2,2,2,"<_");        gr->Title("Minus-log axis");    gr->SetRanges(-100,-0.01,-100,-0.1);    gr->SetFunc("-lg(-x)","-lg(-y)");\r
index 10fdcfd190b555e7554f88b78c0a5e3f36661a0f..1a5f13e09f4c291f4bd8e2e6ef0fc06932b80791 100644 (file)
@@ -32,6 +32,19 @@ int sample_d(mglGraph *gr);
 mglPoint pnt;  // some global variable for changable data\r
 void *mgl_qt_tmp(void *);\r
 //-----------------------------------------------------------------------------\r
+class Foo : public mglDraw\r
+{\r
+public:\r
+       int Draw(mglGraph *gr);\r
+} foo;\r
+//-----------------------------------------------------\r
+int Foo::Draw(mglGraph *gr)\r
+{\r
+       gr->Rotate(60,40);\r
+       gr->Box();\r
+       return 0;\r
+}\r
+//-----------------------------------------------------\r
 int main(int argc,char **argv)\r
 {\r
 #ifdef PTHREAD_SAMPLE\r
@@ -58,12 +71,12 @@ int main(int argc,char **argv)
        else    printf("You may specify argument '1', '2', '3' or 'd' for viewing examples of 1d, 2d, 3d or dual plotting\n");\r
        switch(key)\r
        {\r
-       case '1':       gr = new mglWindow(1,sample_1,"1D plots");      break;\r
-       case '2':       gr = new mglWindow(1,sample_2,"2D plots");      break;\r
-       case '3':       gr = new mglWindow(1,sample_3,"3D plots");      break;\r
-       case 'd':       gr = new mglWindow(1,sample_d,"Dual plots");    break;\r
-       case 't':       gr = new mglWindow(1,test_wnd,"Testing");       break;\r
-       default:        gr = new mglWindow(1,sample,"Drop and waves");  break;\r
+       case '1':       gr = new mglWindow(sample_1,"1D plots",1);      break;\r
+       case '2':       gr = new mglWindow(sample_2,"2D plots",1);      break;\r
+       case '3':       gr = new mglWindow(sample_3,"3D plots",1);      break;\r
+       case 'd':       gr = new mglWindow(sample_d,"Dual plots",1);    break;\r
+       case 't':       gr = new mglWindow(test_wnd,"Testing",1);       break;\r
+       default:        gr = new mglWindow(&foo,"Drop and waves",1);    break;\r
        }\r
        gr->Run();      return 0;\r
 #endif\r
index e2680750b010d45318d19ebce1b8b3a519882f88..b1c01c6ea85a6787ac1170346e683db00d647db6 100644 (file)
@@ -43,7 +43,7 @@ void mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add
 void mgl_tune_ticks(HMGL gr, int tune, float fact_pos);\r
 void mgl_set_tick_templ(HMGL gr, char dir, const char *templ);\r
 void mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ);\r
-void mgl_set_tick_time(HMGL gr, char dir, float d, const char *t);\r
+void mgl_set_ticks_time(HMGL gr, char dir, float d, const char *t);\r
 \r
 void mgl_box(HMGL graph);\r
 void mgl_box_str(HMGL gr, const char *col, int ticks);\r
@@ -155,7 +155,7 @@ void mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *ad
 void mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int l);\r
 void mgl_tune_ticks_(uintptr_t *gr, int *tune, float *fact_pos);\r
 void mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int l);\r
-void mgl_set_tick_time_(uintptr_t *gr, const char *dir, float *d, const char *t,int,int l);\r
+void mgl_set_ticks_time_(uintptr_t *gr, const char *dir, float *d, const char *t,int,int l);\r
 void mgl_box_(uintptr_t *gr);\r
 void mgl_box_str_(uintptr_t *gr, const char *col, int *ticks, int l);\r
 void mgl_axis_(uintptr_t *gr, const char *dir, const char *stl,int,int);\r
index 1d7552cfa10f1513b347e760a660d8482fb04cc3..a05d16b7df44f2006e622500a59338c39daa3f83 100644 (file)
@@ -38,7 +38,7 @@
 #define chdir  _chdir // BORLAND has chdir\r
 #include <float.h>\r
 \r
-extern mglData s;const unsigned long mgl_nan[2] = {0xffffffff, 0x7fffffff};\r
+const unsigned long mgl_nan[2] = {0xffffffff, 0x7fffffff};\r
 #define NANd   (*(double*)mgl_nan)\r
 #define NANf   (*(float*)&(mgl_nan[1]))\r
 #if (MGL_USE_DOUBLE==1)\r
index 847ac5221689f4d6c954fb9e9ea05293befb6f2e..6a39fa00101ad5eb4252ca43963a5b3ee7cf49bc 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _MGL_H_\r
 #define _MGL_H_\r
 \r
+#include "mgl/define.h"\r
 #include "mgl/mgl_cf.h"\r
 #include "mgl/data.h"\r
 #ifndef NO_OPENGL\r
@@ -175,8 +176,8 @@ public:
        {       mgl_set_axis_stl(gr, stl, tck, sub);    }\r
 \r
        /// Set time templates for ticks\r
-       inline void SetTickTime(char dir, float d=0, const char *t="")\r
-       {       mgl_set_tick_time(gr,dir,d,t);  }\r
+       inline void SetTicksTime(char dir, float d=0, const char *t="")\r
+       {       mgl_set_ticks_time(gr,dir,d,t); }\r
        /// Set ticks text (\n separated). Use "" to disable this feature.\r
        inline void SetTicksVal(char dir, const char *lbl, bool add=false)\r
        {       mgl_set_ticks_str(gr,dir,lbl,add);      }\r
index cd86191961fcac55f00cfc30bda9a535738db2eb..b2dcf20d3bd2cf38b483359a5d1e5c396bbe5204 100644 (file)
 /// Make inherited class and redefine Draw() function if you don't want to use function pointers.\r
 struct mglDraw\r
 {\r
+       virtual int Draw(mglGraph *){}  ///< Function for drawing\r
+       virtual void Reload()   {}              ///< Function for reloading data\r
 #ifdef HAVE_PTHREAD\r
        pthread_t thr;\r
        bool running;\r
        mglDraw()       {       running=false;  }\r
-       virtual void Calc()     {}      ///< Function for calculations\r
-       inline void Run()               ///< Run calculations in other thread\r
+       virtual void Calc()     {}                      ///< Function for calculations\r
+       inline void Run()                               ///< Run calculations in other thread\r
        {       mgl_draw_thr(this);     }\r
 #endif\r
-       virtual int Draw(mglGraph *)=0; ///< Function for drawing\r
-       virtual void Reload()   {}      ///< Function for reloading data\r
 };\r
-int mgl_draw_class(mglBase *gr, void *p);\r
 void mgl_reload_class(void *p);\r
 typedef int (*draw_func)(mglGraph *gr);\r
 int mgl_draw_graph(mglBase *gr, void *p);\r
+// NOTE: mgl_draw_class() use mglWindow* only. Don't use it with inherited classes\r
+int mgl_draw_class(mglBase *gr, void *p);\r
 //-----------------------------------------------------------------------------\r
+#ifndef HAVE_QT\r
+#define MGL_WND_KIND   0\r
+#else\r
+#define MGL_WND_KIND   1\r
+#endif\r
 class mglWindow : public mglGraph\r
 {\r
+friend int mgl_draw_class(mglBase *gr, void *p);\r
 protected:\r
+       mglDraw *dr;\r
        int wnd;        ///< Type of window\r
 public:\r
-       mglWindow(int kind=0, int (*draw)(HMGL gr, void *p)=NULL, const char *title="MathGL", void *par=NULL) : mglGraph(-1)\r
+       mglWindow(int (*draw)(HMGL gr, void *p)=NULL, const char *title="MathGL", void *par=NULL, int kind=MGL_WND_KIND) : mglGraph(-1)\r
        {\r
-               wnd=kind;\r
+               wnd=kind;       dr=0;\r
                if(wnd==1)      gr = mgl_create_graph_qt(draw,title,par);\r
                else            gr = mgl_create_graph_fltk(draw,title,par);\r
        }\r
-       mglWindow(int kind, int (*draw)(mglGraph *gr), const char *title="MathGL") : mglGraph(-1)\r
+       mglWindow(int (*draw)(mglGraph *gr), const char *title="MathGL", int kind=MGL_WND_KIND) : mglGraph(-1)\r
        {\r
-               wnd=kind;\r
+               wnd=kind;       dr=0;\r
                if(wnd==1)      gr = mgl_create_graph_qt(mgl_draw_graph,title,(void*)draw);\r
                else            gr = mgl_create_graph_fltk(mgl_draw_graph,title,(void*)draw);\r
        }\r
-       mglWindow(int kind=0, mglDraw *dr=NULL, const char *title="MathGL") : mglGraph(-1)\r
+       mglWindow(mglDraw *draw, const char *title="MathGL", int kind=MGL_WND_KIND) : mglGraph(-1)\r
        {\r
-               wnd=kind;\r
-               if(wnd==1)      gr = mgl_create_graph_qt(mgl_draw_class,title,dr);\r
-               else            gr = mgl_create_graph_fltk(mgl_draw_class,title,dr);\r
+               wnd=kind;       dr=draw;\r
+               if(wnd==1)      gr = mgl_create_graph_qt(mgl_draw_class,title,this);\r
+               else            gr = mgl_create_graph_fltk(mgl_draw_class,title,this);\r
        }\r
        inline int Run()                        ///< Run main loop for event handling\r
        {       return (wnd==1)? mgl_qt_run() : mgl_fltk_run(); }\r
index a0e2d82ff1f4979df5021912b29189dce45101f1..35f070a4c3afb10fdcdb2a91f7efcde78186c167 100644 (file)
@@ -280,8 +280,8 @@ void mglCanvas::SetTickTime(char dir, float d, const char *t)
 //-----------------------------------------------------------------------------
 void mglCanvas::AdjustTicks(const char *dir, bool force)
 {
-       if(force)       SetTuneTicks(true);
-       UpdateAxis();   //TuneTicks = true;
+       if(force)       SetTuneTicks(-1);
+       UpdateAxis();
        if(strchr(dir,'x'))
        {       if(force)       ax.d=0; AdjustTicks(ax,fx);     }
        if(strchr(dir,'y'))
@@ -422,6 +422,8 @@ void mglCanvas::LabelTicks(mglAxis &aa)
                int kind=0;
                wchar_t s[32]=L"";
                if(aa.t[0]==0 && TuneTicks) kind = mgl_tick_ext(aa.v2, aa.v1, s, w);
+               if((TuneTicks&1)==0 && kind==2) kind=0;
+               if((TuneTicks&2)==0 && kind!=2) kind=0;
 
                v0 = isnan(aa.o) ? aa.v0 : aa.o;
                if(aa.v2>aa.v1)
@@ -503,7 +505,7 @@ void mglCanvas::DrawAxis(mglAxis &aa, bool text, char arr,const char *stl)
        {
                v = aa.txt[i].val;      u = fabs(v);
                if(v>=aa.v1 && v<=aa.v2)        tick_draw(o+d*v, da, db, 0, stl);
-               else    tick_draw(o+d*v, da, db, 0, " ");
+//             else    tick_draw(o+d*v, da, db, 0, " ");
                if(aa.dv==0 && fabs(u-exp(M_LN10*floor(0.1+log10(u))))<0.01*u)
                        for(j=2;j<10 && v*j<aa.v2;j++)  tick_draw(o+d*(v*j),da,db,1,stl);
        }
@@ -701,7 +703,7 @@ void mglCanvas::Labelw(char dir, const wchar_t *text, float pos, float shift)
        if(pos<-0.2)    ff[1]='L';      if(pos>0.2)     ff[1]='R';
        strcpy(font,FontDef);   strcat(font,ff);
        strcat(font,nn.y>1e-5 || nn.x<0 ? "T":"t");
-       text_plot(AddPnt(p,-1,q,0,7),text,font,-1.4,0.3+shift);
+       text_plot(AddPnt(p,-1,q,0,7),text,font,-1.4,0.35+shift);
 }
 //-----------------------------------------------------------------------------
 void mglCanvas::Label(float x, float y, const char *str, const char *font, bool rel)
@@ -815,7 +817,7 @@ void mglCanvas::Colorbar(const char *sch, float x, float y, float w, float h)
        mglData v(n);
        if(ac.d || Min.c*Max.c<=0)      v.Fill(Min.c,Max.c);
        else if(Max.c>Min.c && Min.c>0)
-       {       v.Fill(log(Min.c), log(Max.c)); v.Modify("exp(u)");             }
+       {       v.Fill(log(Min.c), log(Max.c));         v.Modify("exp(u)");             }
        else if(Min.c<Max.c && Max.c<0)
        {       v.Fill(log(-Min.c), log(-Max.c));       v.Modify("-exp(u)");    }
        float *c=new float[n];
index 28c0e45b806c0d0bb25e3a4e853e66abe913959c..dcfaa08137f24f87d875860d085ca65b9cbf9a4c 100644 (file)
@@ -98,7 +98,7 @@ GifFileType *gif;*/
        SetTranspType(0);               SetMeshNum(0);  // NOTE: default MeshNum=0\r
        SetRotatedText(true);   CurrPal = 0;\r
        SetLegendMarks();               SetFontSize(4);\r
-       SetTuneTicks(true);     SetAmbient();\r
+       SetTuneTicks(-1);       SetAmbient();\r
        PlotId = "frame";               clr(MGL_DISABLE_SCALE);\r
        SetDefScheme("BbcyrR"); SetPalette(MGL_DEF_PAL);\r
        SetPenPal("k-1");\r
@@ -534,10 +534,9 @@ void mglCanvas::Zoom(float x1, float y1, float x2, float y2)
 {\r
        Bp.clear();             ClfZB();\r
        if(x1==x2 || y1==y2)    {       x1=y1=0;        x2=y2=1;        }\r
-       if(x1<x2)       {       Bp.x=x1;        Bp.b[0]=x2-x1;  }\r
-       else            {       Bp.x=x2;        Bp.b[0]=x1-x2;  }\r
-       if(y1<y2)       {       Bp.y=y1;        Bp.b[4]=y2-y1;  }\r
-       else            {       Bp.y=y2;        Bp.b[4]=y1-y2;  }\r
+       x1=2*x1-1;      x2=2*x2-1;      y1=2*y1-1;      y2=2*y2-1;\r
+       Bp.b[0]=2/fabs(x2-x1);  Bp.b[4]=2/fabs(y2-y1);\r
+       Bp.x=(x1+x2)/2/Bp.b[0]; Bp.y=(y1+y2)/2/Bp.b[4];\r
 }\r
 //-----------------------------------------------------------------------------\r
 int mglCanvas::GetSplId(long x,long y)\r
index 90b9a1994b0bf1a1bad15c266775a472570cd74e..135ba1d93508f891d156b8ff3f727995366d8594 100644 (file)
@@ -227,7 +227,7 @@ void mgl_set_tick_templ(HMGL gr, char dir, const char *templ)
 {      _Gr_->SetTickTempl(dir,templ);  }\r
 void mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ)\r
 {      _Gr_->SetTickTempl(dir,templ);  }\r
-void mgl_set_tick_time(HMGL gr, char dir, float d, const char *t)\r
+void mgl_set_ticks_time(HMGL gr, char dir, float d, const char *t)\r
 {      _Gr_->SetTickTime(dir,d,t);     }\r
 //-----------------------------------------------------------------------------\r
 void mgl_box(HMGL gr)  {       _Gr_->Box();    }\r
@@ -302,7 +302,7 @@ void mgl_tune_ticks_(uintptr_t *gr, int *tune, float *fact_pos)
 void mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int l)\r
 {      char *s=new char[l+1];  memcpy(s,templ,l);      s[l]=0;\r
        _GR_->SetTickTempl(*dir,s);     delete []s;     }\r
-void mgl_set_tick_time_(uintptr_t *gr, const char *dir, float *d, const char *t,int,int l)\r
+void mgl_set_ticks_time_(uintptr_t *gr, const char *dir, float *d, const char *t,int,int l)\r
 {      char *s=new char[l+1];  memcpy(s,t,l);  s[l]=0;\r
        _GR_->SetTickTime(*dir,*d,s);   delete []s;     }\r
 //-----------------------------------------------------------------------------\r
index 9deec10823b518950fb4910f2b6fb6cf2abfe953..6378301dbdedfe177686140c76da5c94c1de80a1 100644 (file)
@@ -1671,7 +1671,7 @@ void mglc_tuneticks(wchar_t out[1024], long , mglArg *a, int k[10], const char *
 //-----------------------------------------------------------------------------
 int mgls_ticktime(mglGraph *gr, long , mglArg *a, int k[10], const char *)
 {
-       if(k[0]==2)     gr->SetTickTime(a[0].s[0],k[1]==3?a[1].v:0,k[2]==2?a[2].s.c_str():"");
+       if(k[0]==2)     gr->SetTicksTime(a[0].s[0],k[1]==3?a[1].v:0,k[2]==2?a[2].s.c_str():"");
        else    return 1;
        return 0;
 }
index 5ad1a6b53206653adaf3227eb6fcc3d16625211c..73cf5475955c9a13dc6b461aef3e24066fba2c20 100644 (file)
@@ -315,8 +315,8 @@ void mglCanvas::pxl_transform(unsigned long id, unsigned long n, const void *)
        {\r
                mglPnt &p=Pnt[i];\r
                x = p.xx-Width/2.;      y = p.yy-Height/2.;     z = p.zz-Depth/2.;\r
-               p.x = Bp.x*Width + Width/2 + Bp.b[0]*x + Bp.b[1]*y + Bp.b[2]*z;\r
-               p.y = Bp.y*Height+ Height/2+ Bp.b[3]*x + Bp.b[4]*y + Bp.b[5]*z;\r
+               p.x = Width/2 - Bp.x*Width/2 + Bp.b[0]*x + Bp.b[1]*y + Bp.b[2]*z;\r
+               p.y = Height/2- Bp.y*Height/2+ Bp.b[3]*x + Bp.b[4]*y + Bp.b[5]*z;\r
                p.z = Depth/2. + Bp.b[6]*x + Bp.b[7]*y + Bp.b[8]*z;\r
                if(Bp.pf)\r
                {\r
index 796f0ee9d0b4543ba8a8b73cb483ab02836ca12e..363942600d31fa93b147c928025bfc153c5addb2 100644 (file)
@@ -260,7 +260,7 @@ Sets approximate number of lines in @ref{mesh}, @ref{fall}, @ref{grid} and also
 @end ifclear
 @cindex Cut
 
-These variables and functions set the condition when the points are excluded (cutted) from the drawing. Note, that a point with NAN value(s) of coordinate or amplitude will be automatically excluded from the drawing. @sref{Cut sample}
+These variables and functions set the condition when the points are excluded (cutted) from the drawing. Note, that a point with NAN value(s) of coordinate or amplitude will be automatically excluded from the drawing. @sref{Cutting sample}
 
 @anchor{cut}
 @deftypefn {MGL command} {} cut @code{val}
@@ -626,16 +626,16 @@ Set template @var{templ} for x-,y-,z-axis ticks or colorbar ticks. It may contai
 
 @deftypefn {MGL command} {} ticktime 'dir' [@code{dv} 'tmpl']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} SetTickTime (@code{char} dir, @code{float} val, @code{const char *}templ)
-@deftypefnx {C function} @code{void} mgl_set_tick_time (@code{HMGL} gr, @code{float} val, @code{const char *}templ)
+@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksTime (@code{char} dir, @code{float} val, @code{const char *}templ)
+@deftypefnx {C function} @code{void} mgl_set_ticks_time (@code{HMGL} gr, @code{float} val, @code{const char *}templ)
 @end ifclear
 Set time labels with step @var{val} and template @var{templ} for x-,y-,z-axis ticks or colorbar ticks. It may contain TeX symbols also. The format of template @var{templ} is the same as described in @url{http://www.manpagez.com/man/3/strftime/}. Most common variants are @samp{%X} for national representation of time, @samp{%x} for national representation of date, @samp{%Y} for year with century. If @var{val}=0 and/or @var{templ}="" then automatic tick step and/or template will be selected.
 @end deftypefn
 
 @deftypefn {MGL command} {} tuneticks @code{val} [@code{pos=1.15}]
-@deftypefnx {Method on @code{mglGraph}} @code{void} SetTuneTicks (@code{bool} tune, @code{float} pos=@code{1.15})
-@deftypefnx {C function} @code{void} mgl_tune_ticks (@code{HMGL} gr, @code{bool} tune, @code{float} pos)
-Switch on/off ticks enhancing by factoring common multiplier (for small, like from 0.001 to 0.002, or large, like from 1000 to 2000, coordinate values) or common component (for narrow range, like from 0.999 to 1.000). Also set the position @var{pos} of common multiplier/component on the axis: =0 at minimal axis value, =1 at maximal axis value. Default value is 1.15.
+@deftypefnx {Method on @code{mglGraph}} @code{void} SetTuneTicks (@code{int} tune, @code{float} pos=@code{1.15})
+@deftypefnx {C function} @code{void} mgl_tune_ticks (@code{HMGL} gr, @code{int} tune, @code{float} pos)
+Switch on/off ticks enhancing by factoring common multiplier (for small, like from 0.001 to 0.002, or large, like from 1000 to 2000, coordinate values -- enabled if @var{tune}&1 is nonzero) or common component (for narrow range, like from 0.999 to 1.000 -- enabled if @var{tune}&2 is nonzero). Also set the position @var{pos} of common multiplier/component on the axis: =0 at minimal axis value, =1 at maximal axis value. Default value is 1.15.
 @end deftypefn
 
 @ifclear UDAV
@@ -684,7 +684,7 @@ The line style of axis, (@var{stl}) ticks (@var{tck}) and subticks (@var{sub}).
 @cindex Push
 @cindex Pop
 
-These functions control how and where further plotting will be placed. There is a certain calling order of these functions for the better plot appearance. First one should be @ref{subplot}, @ref{multiplot} or @ref{inplot} for specifying the place. Second one can be @ref{title} for adding title for the subplot. After it a @ref{rotate} and @ref{aspect}. And finally any other plotting functions may be called. Alternatively you can use @ref{columnplot}, @ref{gridplot}, @ref{stickplot} or relative @ref{inplot} for positioning plots in the column (or grid, or stick) one by another without gap between plot axis (bounding boxes). @sref{InPlot sample}
+These functions control how and where further plotting will be placed. There is a certain calling order of these functions for the better plot appearance. First one should be @ref{subplot}, @ref{multiplot} or @ref{inplot} for specifying the place. Second one can be @ref{title} for adding title for the subplot. After it a @ref{rotate} and @ref{aspect}. And finally any other plotting functions may be called. Alternatively you can use @ref{columnplot}, @ref{gridplot}, @ref{stickplot} or relative @ref{inplot} for positioning plots in the column (or grid, or stick) one by another without gap between plot axis (bounding boxes). @sref{Subplots}
 
 @anchor{subplot}
 @deftypefn {MGL command} {} subplot @code{nx ny m ['stl'='<>_^' dx=0 dy=0]}
@@ -1397,7 +1397,7 @@ These functions draw the ``things for measuring'', like axis with ticks, colorba
 @deftypefnx {Method on @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""})
 @deftypefnx {C function} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl)
 @end ifclear
-Draws axes with ticks (see @ref{Axis settings}) in directions determined by string parameter @var{dir}.If string contain the symbol @samp{_} then tick labels are not printed. Font for ticks labels is determined by @var{FontDef} (see @ref{Font settings}). Ticks will be adjusted if @var{stl} contain @samp{a} (by call of @code{AdjustTicks()}). You can specified an arrow at the end of axis (see see @ref{Line styles}). Styles of ticks and axis can be overrided by using @var{stl} string.
+Draws axes with ticks (see @ref{Axis settings}) in directions determined by string parameter @var{dir}.If string contain the symbol @samp{_} then tick labels are not printed. Font for ticks labels is determined by @var{FontDef} (see @ref{Font settings}). Ticks will be adjusted if @var{stl} contain @samp{a} (by call of @code{AdjustTicks()}). You can specified an arrow at the end of axis (see see @ref{Line styles}). Styles of ticks and axis can be overrided by using @var{stl} string. @sref{Axis and ticks}
 @end deftypefn
 
 @anchor{colorbar}
@@ -1406,7 +1406,7 @@ Draws axes with ticks (see @ref{Axis settings}) in directions determined by stri
 @deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch=@code{""})
 @deftypefnx {C function} @code{void} mgl_colorbar (@code{HMGL} gr, @code{const char *}sch)
 @end ifclear
-Draws colorbar with color scheme @var{sch} (current scheme if @code{sch=""}) at edge of plot. If string @var{sch} contains @samp{<>^_} then the colorbar is placed at left, at right, at top or at bottom correspondingly. If string have @samp{I} then colorbar will be located near bounding box otherwise at the edge of the subplot. If string have @samp{A} then absolute (relative to picture) coordinates is used. @sref{Dens sample}
+Draws colorbar with color scheme @var{sch} (current scheme if @code{sch=""}) at edge of plot. If string @var{sch} contains @samp{<>^_} then the colorbar is placed at left, at right, at top or at bottom correspondingly. If string have @samp{I} then colorbar will be located near bounding box otherwise at the edge of the subplot. If string have @samp{A} then absolute (relative to picture) coordinates is used. @sref{Colorbars}
 @end deftypefn
 
 @deftypefn {MGL command} {} colorbar vdat ['sch'='']
index 8875abe0101c243245600e1af5429a8665d21405..1aaaf7e97b82bb874a34e97fc430a0464f558765 100644 (file)
@@ -13,8 +13,6 @@ This chapter contain information about basic and advanced MathGL, hints and samp
 * 3D samples::
 * Dual samples::
 * More samples::
-* C/Fortran interface::
-* MathGL and PyQt::
 * Hints::
 * FAQ::
 @end menu
@@ -26,26 +24,38 @@ This chapter contain information about basic and advanced MathGL, hints and samp
 MathGL library can be used by several manners. Each has positive and negative sides:
 @itemize @bullet
 @item
-@emph{The using of MathGL library features for creating graphical window (requires FLTK or GLUT libraries).}
+@emph{Using of MathGL library features for creating graphical window (requires FLTK, Qt or GLUT libraries).}
 
 Positive side is the possibility to view the plot at once and to modify it (rotate, zoom or switch on transparency or lighting) by hand or by mouse. Negative sides are: the need  of X-terminal and limitation consisting in working with the only one set of data at a time.
+
 @item
 @emph{Direct writing to file in bitmap or vector format without creation of graphical window.}
 
 Positive aspects are: batch processing of similar data set (for example, a set of resulting data files for different calculation parameters), running from the console program (including the cluster calculation), fast and automated drawing, saving pictures for further analysis (or demonstration). Negative sides are: the usage of the external program for picture viewing. Also, the data plotting is non-visual. So, you have to imagine the picture (view angles, lighting and so on) before the plotting. I recommend to use graphical window for determining the optimal parameters of plotting on the base of some typical data set. And later use these parameters for batch processing in console program.
+
 @item
 @emph{Drawing in memory with the following displaying by other graphical program.}
 
-In this case the programmer has more freedom in selecting the window libraries (not only FLTK or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``settled'' programs.
+In this case the programmer has more freedom in selecting the window libraries (not only FLTK, Qt or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``settled'' programs.
+
+@item
+@emph{Using FLTK or Qt widgets provided by MathGL}
+
+Here one can use a set of standard widgets which support export to many file formats, copying to clipboard, handle mouse and so on. 
 @end itemize
 
+MathGL drawing can be created not only by object oriented languages (like, C++ or Python), but also by pure C or Fortran-like languages. The usage of last one is mostly identical to usage of classes (except the different function names). But there are some differences. C functions must have argument HMGL (for graphics) and/or HMDT (for data arrays) which specifies the object for drawing or manipulating (changing). Fortran users may regard these variables as integer. So, firstly the user has to create this object by function mgl_create_*() and has to delete it after the using by function mgl_delete_*().
+@c Also, all arguments of C function have to be defined. So there are several functions with practically identical names doing practically the same. But some of them have simplified interface for the quick plotting and some of them have access to all plotting parameters for manual tunning.
+
 Let me consider the aforesaid in more detail.
 
 @menu
 * Using MathGL window::
 * Drawing to file::
+* Animation::
 * Drawing in memory::
 * Using QMathGL::
+* MathGL and PyQt::
 @end menu
 
 
@@ -57,237 +67,393 @@ Let me consider the aforesaid in more detail.
 
 The ``interactive'' way of drawing in MathGL consists in window creation  with help of class @code{mglWindow} or @code{mglGLUT} (see @ref{Widget classes}) and the following drawing in this window. There is a corresponding code:
 @verbatim
-    int sample(mglGraph *gr)
-    {
-        gr->Rotate(60,40);
-        gr->Box();
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mglWindow gr(0,sample,"MathGL examples");
-        return gr.Run();
-    }
+#include <mgl/window.h>
+int sample(mglGraph *gr)
+{
+  gr->Rotate(60,40);
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  mglWindow gr(sample,"MathGL examples");
+  return gr.Run();
+}
+@end verbatim
+Here function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program. For compilation, just execute the command
+@verbatim
+gcc test.cpp -lmgl-wnd -lmgl
 @end verbatim
-Here function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program.
 
 Alternatively you can create yours own class inherited from class @code{mglDraw} and re-implement the function @code{Draw()} in it:
 @verbatim
-    class Foo : public mglDraw
-    {
-    public:
-        int Draw(mglGraph *gr);
-    };
-    //-----------------------------------------------------
-    int Foo::Draw(mglGraph *gr)
-    {
-        gr->Rotate(60,40);
-        gr->Box();
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mglDraw foo;
-        mglWindow gr(0,&foo,"MathGL examples");
-        return gr.Run();
-    }
+#include <mgl/window.h>
+class Foo : public mglDraw
+{
+public:
+  int Draw(mglGraph *gr);
+};
+//-----------------------------------------------------
+int Foo::Draw(mglGraph *gr)
+{
+  gr->Rotate(60,40);
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  Foo foo;
+  mglWindow gr(&foo,"MathGL examples");
+  return gr.Run();
+}
+@end verbatim
+Or use pure C-functions:
+@verbatim
+#include <mgl/mgl_cf.h>
+int sample(HMGL gr)
+{
+  mgl_rotate(gr,60,40,0);
+  mgl_box(gr);
+}
+int main(int argc,char **argv)
+{
+  HMGL gr;
+  gr = mgl_create_graph_qt(sample,"MathGL examples",0);
+  return mgl_qt_run();
+/* generally I should call mgl_delete_graph() here,
+ * but I omit it in main() function. */
+}
 @end verbatim
 
 The similar code can be written for @code{mglGLUT} window (function @code{sample()} is the same):
 @verbatim
-    int main(int argc,char **argv)
-    {
-        mglGLUT gr(sample,"MathGL examples");
-        return 0;
-    }
+#include <mgl/glut.h>
+int main(int argc,char **argv)
+{
+  mglGLUT gr(sample,"MathGL examples");
+  return 0;
+}
 @end verbatim
 
 The rotation, shift, zooming, switching on/off transparency and lighting can be done with help of tool-buttons (for @code{mglWindow}) or by hot-keys: @samp{a}, @samp{d}, @samp{w}, @samp{s} for plot rotation, @samp{r} and @samp{f} switching on/off transparency and lighting. Press @samp{x} for exit (or closing the window).
 
-In this example function @code{sample} rotates axes (@code{Rotate()}, @pxref{Transformation matrix}) and draws the bounding box (@code{Box()}). Drawing procedure is separated in a function since it will be used on demand when window canvas needs to be redrawn. Widget classes (@code{mglWindow}, @code{mglGLUT}) support a delayed drawing, when all plotting functions are called once at the beginning of writing to memory lists. Further program displays the saved lists faster. Resulting redrawing will be faster but it requires sufficient memory. Several lists (frames) can be displayed one after another (by pressing @samp{,}, @samp{.}) or run as cinema. To switch these feature on one needs to modify function @code{sample}:
+In this example function @code{sample} rotates axes (@code{Rotate()}, @pxref{Transformation matrix}) and draws the bounding box (@code{Box()}). Drawing is placed in separate function since it will be used on demand when window canvas needs to be redrawn.
+
+@c ------------------------------------------------------------------
+@node Drawing to file, Animation, Using MathGL window, Basic usage
+@subsection Drawing to file
+
+Another way of using MathGL library is the direct writing of the picture to the file. It is most usable for plot creation during long calculation or for using of small programs (like Matlab or Scilab scripts) for visualizing repetitive sets of data. But the speed of drawing is much higher in comparison with a script language.
+
+The following code produces a bitmap PNG picture:
+@verbatim
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  gr.Alpha(true);   gr.Light(true);
+  sample(&gr);              // The same drawing function.
+  gr.WritePNG("test.png");  // Don't forget to save the result!
+  return 0;
+}
+@end verbatim
+ For compilation, you need only libmgl library not the one with widgets
+@verbatim
+gcc test.cpp -lmgl
+@end verbatim
+This can be important if you create a console program in computer/cluster where X-server (and widgets) is inaccessible.
+
+The only difference from the previous variant (using windows) is manual switching on the transparency  @code{Alpha} and lightning @code{Light}, if you need it. The usage of frames (see @ref{Animation}) is not advisable since the whole image is prepared each time. If function @code{sample} contains frames then only last one will be saved to the file. In principle, one does not need to separate drawing functions in case of direct file writing in consequence of the single calling of this function for each picture. However, one may use the same drawing procedure to create a plot with changeable parameters, to export in different file types, to emphasize the drawing code and so on. So, in future I will put the drawing in the separate function.
+
+The code for export in vector EPS file looks the same:
 @verbatim
-    int sample1(mglGraph *gr, void *)
-    {
-        gr->NewFrame();             // the first frame
-        gr->Rotate(60,40);
-        gr->Box();
-        gr->EndFrame();             // end of the first frame
-        gr->NewFrame();             // the second frame
-        gr->Box();
-        gr->Axis("xy");
-        gr->EndFrame();             // end of the second frame
-        return GetNumFrame();       // returns the frame number
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  gr.Light(true);
+  sample(&gr);              // The same drawing function.
+  gr.WriteEPS("test.eps");  // Don't forget to save the result!
+  return 0;
+}
+@end verbatim
+The difference from the previous one is using other function @code{WriteEPS()} for EPS format instead of function @code{WritePNG()}. Also, there is no switching on of the plot transparency @code{Alpha} since EPS format does not support it.
+
+@c ------------------------------------------------------------------
+@node Animation, Drawing in memory, Drawing to file, Basic usage
+@subsection Animation
+
+Widget classes (@code{mglWindow}, @code{mglGLUT}) support a delayed drawing, when all plotting functions are called once at the beginning of writing to memory lists. Further program displays the saved lists faster. Resulting redrawing will be faster but it requires sufficient memory. Several lists (frames) can be displayed one after another (by pressing @samp{,}, @samp{.}) or run as cinema. To switch these feature on one needs to modify function @code{sample}:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->NewFrame();             // the first frame
+  gr->Rotate(60,40);
+  gr->Box();
+  gr->EndFrame();             // end of the first frame
+  gr->NewFrame();             // the second frame
+  gr->Box();
+  gr->Axis("xy");
+  gr->EndFrame();             // end of the second frame
+  return gr->GetNumFrame();   // returns the frame number
+}
 @end verbatim
 First, the function creates a frame @code{NewFrame()} for rotated axes and draws the bounding box. After the frame drawing the function @code{EndFrame()} @strong{must be} called! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
 
 Note, that such kind of animation is rather slow and not well suitable for visualization of running calculations. For the last case one can use @code{Update()} function. The most simple case for doing this is to use @code{mglDraw} class and reimplement its @code{Calc()} method.
 @verbatim
-    class Foo : public mglDraw
-    {
-        mglPoint pnt;  // some result of calculation
-    public:
-        mglGraph *Gr;  // graphics to be updated
-        int Draw(mglGraph *gr);
-        void Calc();
-    } foo;
-    //-----------------------------------------------------
-    int Foo::Calc()
-    {
-        for(int i=0;i<30;i++)   // do calculation
-        {
-            sleep(2);           // which can be very long
-            pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-            Gr.Update();        // update window
-        }
-    }
-    //-----------------------------------------------------
-    int Foo::Draw(mglGraph *gr)
-    {
-        gr.Line(mglPoint(),pnt,"Ar2");
-        gr->Box();
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mglDraw foo;
-        mglWindow gr(0,&foo,"MathGL examples");
-        foo.Gr = &gr;   foo.Run();
-        return gr.Run();
-    }
+#include <mgl/window.h>
+class Foo : public mglDraw
+{
+  mglPoint pnt;  // some result of calculation
+public:
+  mglGraph *Gr;  // graphics to be updated
+  int Draw(mglGraph *gr);
+  void Calc();
+} foo;
+//-----------------------------------------------------
+int Foo::Calc()
+{
+  for(int i=0;i<30;i++)   // do calculation
+  {
+    sleep(2);           // which can be very long
+    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
+    Gr->Update();        // update window
+  }
+}
+//-----------------------------------------------------
+int Foo::Draw(mglGraph *gr)
+{
+  gr->Line(mglPoint(),pnt,"Ar2");
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  mglWindow gr(&foo,"MathGL examples");
+  foo.Gr = &gr;   foo.Run();
+  return gr.Run();
+}
 @end verbatim
 
-@c ------------------------------------------------------------------
-@node Drawing to file, Drawing in memory, Using MathGL window, Basic usage
-@subsection Drawing to file
 
-Another way of using MathGL library is the direct picture writing to file. It is most usable for plot creating during calculation or for using of small programs (like Matlab or Scilab scripts) for visualizing repetitive sets of data. But the speed of drawing is much higher in comparison with a script language.
+Pictures with animation can be saved in file(s) as well. You can: export in animated GIF, or save each frame in separate file (usually JPEG) and convert these files into the movie (for example, by help of ImageMagic). Let me show both methods.
 
-The following code produces a bitmap PNG picture:
+The simplest methods is making animated GIF. There are 3 steps: (1) open GIF file by @code{StartGIF()} function; (2) create the frames by calling @code{NewFrame()} before and @code{EndFrame()} after plotting; (3) close GIF by @code{CloseGIF()} function. So the simplest code for ``running'' sinusoid will look like this:
 @verbatim
-    int main(int ,char **)
-    {
-        mglGraph gr;
-        gr.Alpha(true);
-        gr.Light(true);             gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);           // The same drawing function.
-        gr.WritePNG("test.png");    // Don't forget to save the result!
-        return 0;
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  mglData dat(100);
+  char str[32];
+  gr.StartGIF("sample.gif");
+  for(int i=0;i<40;i++)
+  {
+    gr.NewFrame();     // start frame
+    gr.Box();          // some plotting
+    for(int j=0;j<dat.nx;j++)
+      dat.a[j]=sin(M_PI*j/dat.nx+M_PI*0.05*i);
+    gr.Plot(dat,"b");
+    gr.EndFrame();     // end frame
+  }
+  gr.CloseGIF();
+  return 0;
+}
 @end verbatim
-The only difference from the previous (using windows) variant is manual switching the transparency  @code{Alpha} and lightning @code{Light} on, if the plot requires it. The using of frames is not advisable since the whole image is prepared each time. If function @code{sample} contains frames then each frame will be saved to a separate file. In principle, one does not need to separate drawing functions in case of direct file writing in consequence of the single calling of this function for each picture. However, one may use the same drawing procedure to create a plot with changed parameters, to export in different file types, to emphasize the drawing code and so on. So, in future I will put the drawing in separate function.
 
-The code for export in vector EPS file looks the same:
+The second way is saving each frame in separate file (usually JPEG) and later make the movie from them. MathGL have special function for saving frames -- it is @code{WriteFrame()}. This function save each frame with automatic name @samp{frame0001.jpg, frame0002.jpg} and so on. Here prefix @samp{frame} is defined by @var{PlotId} variable of @code{mglGraph} class. So the similar code will look like this:
 @verbatim
-    int main(int ,char **)
-    {
-        mglGraph gr;
-        gr.Light(true);             gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);           // The same drawing function.
-        gr.WriteEPS("test.eps");    // Don't forget to save the result!
-        return 0;
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  mglData dat(100);
+  char str[32];
+  for(int i=0;i<40;i++)
+  {
+    gr.NewFrame();     // start frame
+    gr.Box();          // some plotting
+    for(int j=0;j<dat.nx;j++)
+      dat.a[j]=sin(M_PI*j/dat.nx+M_PI*0.05*i);
+    gr.Plot(dat,"b");
+    gr.EndFrame();     // end frame
+    gr.WriteFrame();   // save frame
+  }
+  return 0;
+}
 @end verbatim
-The difference from the previous one is using other function @code{WriteEPS()} for EPS format instead of function @code{WritePNG()}. Moreover, there is no switching of the plot transparency @code{Alpha} since EPS format does not support it. Possibly I shall include transparency in future by program emulation.
+
+Created files can be converted to movie by help of a lot of programs. For example, you can use ImageMagic (command @samp{convert frame*.jpg movie.mpg}), MPEG library, GIMP and so on.
+
+Finally, you can use @code{mglconv} tool for doing the same with MGL scripts (@pxref{Utilities}).
 
 @c ------------------------------------------------------------------
-@node Drawing in memory, Using QMathGL, Drawing to file, Basic usage
+@node Drawing in memory, Using QMathGL, Animation, Basic usage
 @subsection Drawing in memory
 
 The last way of MathGL using is the drawing in memory. Class @code{mglGraph} allows one  to create a bitmap picture in memory. Further this picture can be displayed in window by some window libraries (like wxWidgets, FLTK, Windows GDI and so on). For example, the code for drawing in wxWidget library looks like:
 @verbatim
-    void MyForm::OnPaint(wxPaintEvent& event)
-    {
-        int w,h,x,y;
-        GetClientSize(&w,&h);   // size of the picture
-        mglGraph gr(w,h);
-
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-
-        wxImage img(w,h,gr.GetBits(),true);
-        ToolBar->GetSize(&x,&y);    // gets a height of the toolbar if any
-        wxPaintDC dc(this);         // and draws it
-        dc.DrawBitmap(wxBitmap(img),0,y);
-    }
+void MyForm::OnPaint(wxPaintEvent& event)
+{
+  int w,h,x,y;
+  GetClientSize(&w,&h);   // size of the picture
+  mglGraph gr(w,h);
+
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);
+  sample(&gr,NULL);
+
+  wxImage img(w,h,gr.GetBits(),true);
+  ToolBar->GetSize(&x,&y);    // gets a height of the toolbar if any
+  wxPaintDC dc(this);         // and draws it
+  dc.DrawBitmap(wxBitmap(img),0,y);
+}
 @end verbatim
 The drawing in other libraries is most the same.
 
 For example, FLTK code will look like
 @verbatim
-    void Fl_MyWidget::draw()
-    {
-        mglGraph gr(w(),h());
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-        fl_draw_image(gr.GetBits(), x(), y(), gr.GetWidth(), gr.GetHeight(), 3);
-    }
+void Fl_MyWidget::draw()
+{
+  mglGraph gr(w(),h());
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);
+  sample(&gr,NULL);
+  fl_draw_image(gr.GetBits(), x(), y(), gr.GetWidth(), gr.GetHeight(), 3);
+}
 @end verbatim
 Qt code will look like
 @verbatim
-    void MyWidget::paintEvent(QPaintEvent *)
-    {
-        mglGraph gr(w(),h());
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-
-        // Qt don't support RGB format as is. So, let convert it to BGRN.
-        const uchar *bb = gr.GetBits();
-        register long i, w=gr.GetWidth(), h=gr.GetHeight();
-        *buf = new uchar[4*w*h];
-        for(i=0;i<w*h;i++)
-        {
-            (*buf)[4*i]   = bb[3*i+2];
-            (*buf)[4*i+1] = bb[3*i+1];
-            (*buf)[4*i+2] = bb[3*i];
-            (*buf)[4*i+3] = 255;
-        }
-        QPixmap pic = QPixmap::fromImage(QImage(*buf, w, h, QImage::Format_RGB32));
-
-        QPainter paint;
-        paint.begin(this);  paint.drawPixmap(0,0,pic);  paint.end();
-        delete []buf;
-    }
+void MyWidget::paintEvent(QPaintEvent *)
+{
+  mglGraph gr(w(),h());
+
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
+  sample(&gr,NULL);
+
+  // Qt don't support RGB format as is. So, let convert it to BGRN.
+  long w=gr.GetWidth(), h=gr.GetHeight();
+  unsigned char *buf = new uchar[4*w*h];
+  gr.GetBGRN(buf, 4*w*h)
+  QPixmap pic = QPixmap::fromImage(QImage(*buf, w, h, QImage::Format_RGB32));
+
+  QPainter paint;
+  paint.begin(this);  paint.drawPixmap(0,0,pic);  paint.end();
+  delete []buf;
+}
 @end verbatim
 
 @c ------------------------------------------------------------------
-@node Using QMathGL, , Drawing in memory, Basic usage
+@node Using QMathGL, MathGL and PyQt, Drawing in memory, Basic usage
 @subsection Using QMathGL
 
-MathGL have several interface widgets for different widget libraries. There are QMathGL for Qt, Fl_MathGL for FLTK in MathGL v.1.8. These classes provide control which display MathGL graphics. Unfortunately there is no uniform interface for widget classes because all libraries have slightly different set of functions, features and so on. However the usage of MathGL widgets is rather simple. Let me show it on the example of QMathGL.
+MathGL have several interface widgets for different widget libraries. There are QMathGL for Qt, Fl_MathGL for FLTK. These classes provide control which display MathGL graphics. Unfortunately there is no uniform interface for widget classes because all libraries have slightly different set of functions, features and so on. However the usage of MathGL widgets is rather simple. Let me show it on the example of QMathGL.
 
 First of all you have to define the drawing function or inherit a class from @code{mglDraw} class. After it just create a window and setup QMathGL instance as any other Qt widget:
 @verbatim
-    int main(int argc,char **argv)
-    {
-        QApplication a(argc,argv);
-        QMainWindow *Wnd = new QMainWindow;
-        Wnd->resize(650,480);  // for fill up the QMGL, menu and toolbars
-        Wnd->setWindowTitle(title);
-        // here I allow to scroll QMathGL -- the case
-        // then user want to prepare huge picture
-        QScrollArea *scroll = new QScrollArea(Wnd);
-
-        // Create and setup QMathGL
-        QMathGL *QMGL = new QMathGL(Wnd);
-        QMGL->setPopup(popup); // if you want to setup popup menu for QMGL
-        QMGL->setDraw(sample, NULL);
-        // or use QMGL->setDraw(foo); for instance of class Foo:public mglDraw
-        QMGL->update();
-
-        // continue other setup (menu, toolbar and so on)
-        makeMenu();
-        scroll->setWidget(QMGL);
-        Wnd->setCentralWidget(scroll);
-        Wnd->show();
-        return a.exec();
-    }
+#include <QApplication>
+#include <QMainWindow>
+#include <QScrollArea>
+#include <mgl/qt.h>
+int main(int argc,char **argv)
+{
+  QApplication a(argc,argv);
+  QMainWindow *Wnd = new QMainWindow;
+  Wnd->resize(810,610);  // for fill up the QMGL, menu and toolbars
+  Wnd->setWindowTitle("QMathGL sample");
+  // here I allow to scroll QMathGL -- the case
+  // then user want to prepare huge picture
+  QScrollArea *scroll = new QScrollArea(Wnd);
+
+  // Create and setup QMathGL
+  QMathGL *QMGL = new QMathGL(Wnd);
+//QMGL->setPopup(popup); // if you want to setup popup menu for QMGL
+  QMGL->setDraw(sample);
+  // or use QMGL->setDraw(foo); for instance of class Foo:public mglDraw
+  QMGL->update();
+
+  // continue other setup (menu, toolbar and so on)
+  scroll->setWidget(QMGL);
+  Wnd->setCentralWidget(scroll);
+  Wnd->show();
+  return a.exec();
+}
+@end verbatim
+
+@c ------------------------------------------------------------------
+@node MathGL and PyQt, , Using QMathGL, Basic usage
+@subsection MathGL and PyQt
+
+Generally SWIG based classes (including the Python one) are the same as C++ classes. However, there are few tips for using MathGL with PyQt. Below I place a very simple python code which demonstrate how MathGL can be used with PyQt. This code is mostly written by Prof. Dr. Heino Falcke. You can just copy it to a file @code{mgl-pyqt-test.py} and execute it from python shell by command @code{execfile("mgl-pyqt-test.py")}
+
+@verbatim
+from PyQt4 import QtGui,QtCore
+from mathgl import *
+import sys
+app = QtGui.QApplication(sys.argv)
+qpointf=QtCore.QPointF()
+
+class hfQtPlot(QtGui.QWidget):
+    def __init__(self, parent=None):
+        QtGui.QWidget.__init__(self, parent)
+        self.img=(QtGui.QImage())
+    def setgraph(self,gr):
+        self.buffer='\t'
+        self.buffer=self.buffer.expandtabs(4*gr.GetWidth()*gr.GetHeight())
+        gr.GetBGRN(self.buffer,len(self.buffer))
+        self.img=QtGui.QImage(self.buffer, gr.GetWidth(),gr.GetHeight(),QtGui.QImage.Format_ARGB32)
+        self.update()
+    def paintEvent(self, event):
+        paint = QtGui.QPainter()
+        paint.begin(self)
+        paint.drawImage(qpointf,self.img)
+        paint.end()
+
+BackgroundColor=[1.0,1.0,1.0]
+size=100
+gr=mglGraph()
+y=mglData(size)
+#y.Modify("((0.7*cos(2*pi*(x+.2)*500)+0.3)*(rnd*0.5+0.5)+362.135+10000.)")
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+x=mglData(size)
+x.Modify("x^2");
+
+def plotpanel(gr,x,y,n):
+    gr.SubPlot(2,2,n)
+    gr.SetXRange(x)
+    gr.SetYRange(y)
+    gr.AdjustTicks()
+    gr.Axis()
+    gr.Box()
+    gr.Label("x","x-Axis",1)
+    gr.Label("y","y-Axis",1)
+    gr.ClearLegend()
+    gr.AddLegend("Legend: "+str(n),"k")
+    gr.Legend()
+    gr.Plot(x,y)
+
+
+gr.Clf(BackgroundColor[0],BackgroundColor[1],BackgroundColor[2])
+gr.SetPlotFactor(1.5)
+plotpanel(gr,x,y,0)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,1)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,2)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,3)
+
+gr.WritePNG("test.png","Test Plot")
+
+qw = hfQtPlot()
+qw.show()
+qw.setgraph(gr)
+qw.raise_()
 @end verbatim
 
 
@@ -295,286 +461,417 @@ First of all you have to define the drawing function or inherit a class from @co
 @node Advanced usage, Data handling, Basic usage, Examples
 @section Advanced usage
 
-Now I show several non-obvious features of MathGL: several subplots in a single picture, curvilinear coordinates, text printing and so on. Generally you may miss this section at first reading, but I don't recommend it.
+Now I show several non-obvious features of MathGL: several subplots in a single picture, curvilinear coordinates, text printing and so on. Generally you may miss this section at first reading.
 
 @menu
 * Subplots::
-* Axis and grids::
+* Axis and ticks::
 * Curvilinear coordinates::
-* Text printing example::
-* Animation::
+* Colorbars::
+* Ternary axis::
+* Text features::
+* Cutting sample::
 @end menu
 
 @c ------------------------------------------------------------------
-@node Subplots, Axis and grids, , Advanced usage
+@node Subplots, Axis and ticks, , Advanced usage
 @subsection Subplots
 
-Let me demonstrate possibilities of axes transformation. MathGL has the following functions: @code{SubPlot}, @code{InPlot}, @code{Aspect} and @code{Rotate} (@pxref{Transformation matrix}). The order of their calling is strictly determined. First, one changes the position of axes in image area (functions @code{SubPlot} and @code{InPlot}). After that one may rotate the plot (function @code{Rotate}). Finally, one may change aspects of axes (function @code{Aspect}). The following code illustrates the aforesaid it:
+Let me demonstrate possibilities of plot positioning and rotation. MathGL has a set of functions: @code{SubPlot}, @code{InPlot}, @code{Title}, @code{Aspect} and @code{Rotate} and so on (see @ref{Transformation matrix}). The order of their calling is strictly determined. First, one changes the position of plot in image area (functions @code{SubPlot}, @code{InPlot} and @code{MultiPlot}). Secondly, you can add the title of plot by @code{Title} function. After that one may rotate the plot (function @code{Rotate}). Finally, one may change aspects of axes (function @code{Aspect}). The following code illustrates the aforesaid it:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->SubPlot(2,2,0);
-        gr->Box();
-        gr->Puts(mglPoint(-1,1.1,1),"Just box","rL");
-        gr->InPlot(0.2,0.5,0.7,1);
-        gr->Box();
-        gr->Puts(mglPoint(0,1.2,1),"InPlot example");
-
-        gr->SubPlot(2,2,1);
-        gr->Rotate(60,40);
-        gr->Aspect(1,1,1);
-        gr->Box();
-        gr->Puts(mglPoint(1,1,1.5),"Rotate only","rR");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->Aspect(1,1,2);
-        gr->Box();
-        gr->Puts(mglPoint(0,0,2),"Aspect and Rotate");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->Aspect(1,2,2);
-        gr->Box();
-        gr->Puts(mglPoint(0,0,1.5),"Aspect in other direction");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Box();
+  gr->Puts(mglPoint(-1,1.1),"Just box",":L");
+  gr->InPlot(0.2,0.5,0.7,1,false);  gr->Box();
+  gr->Puts(mglPoint(0,1.2),"InPlot example");
+  gr->SubPlot(2,2,1); gr->Title("Rotate only");
+  gr->Rotate(50,60);  gr->Box();
+  gr->SubPlot(2,2,2); gr->Title("Rotate and Aspect");
+  gr->Rotate(50,60);  gr->Aspect(1,1,2);  gr->Box();
+  gr->SubPlot(2,2,3); gr->Title("Aspect in other direction");
+  gr->Rotate(50,60);  gr->Aspect(1,2,2);  gr->Box();
+  return 0;
+}
 @end verbatim
-Here I used function @code{Puts} for printing the text in arbitrary position of picture (@pxref{Text printing}). Text coordinates and size are connected with axes. However, text coordinates may be everywhere, including the outside the bounding box. I shall show its features later in @xref{Text printing example}.
+Here I used function @code{Puts} for printing the text in arbitrary position of picture (see @ref{Text printing}). Text coordinates and size are connected with axes. However, text coordinates may be everywhere, including the outside the bounding box. I'll show its features later in @ref{Text features}.
 
 @float
-@image{../png/sample1, 7cm}
+@image{../png/aspect, 11cm}
 @caption{Example of several subplots on the single picture.}
 @end float
 
+More complicated sample show how to use most of positioning functions:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(3,2,0); gr->Title("StickPlot");
+  gr->StickPlot(3, 0, 20, 30);  gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->StickPlot(3, 1, 20, 30);  gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->StickPlot(3, 2, 20, 30);  gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->SubPlot(3,2,3,"");  gr->Title("ColumnPlot");
+  gr->ColumnPlot(3, 0); gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->ColumnPlot(3, 1); gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->ColumnPlot(3, 2); gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->SubPlot(3,2,4,"");  gr->Title("GridPlot");
+  gr->GridPlot(2, 2, 0);  gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->GridPlot(2, 2, 1);  gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->GridPlot(2, 2, 2);  gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->GridPlot(2, 2, 3);  gr->Box("m"); gr->Puts(mglPoint(0),"3","m");
+  gr->SubPlot(3,2,5,"");  gr->Title("InPlot");  gr->Box();
+  gr->InPlot(0.4, 1, 0.6, 1, true); gr->Box("r");
+  gr->MultiPlot(3,2,1, 2, 1,"");  gr->Title("MultiPlot"); gr->Box();
+  return 0;
+}
+@end verbatim
+
+@float
+@image{../png/inplot, 11cm}
+@caption{Example for most of positioning functions.}
+@end float
+
+
 @c ------------------------------------------------------------------
-@node Axis and grids, Curvilinear coordinates, Subplots, Advanced usage
-@subsection Axis and grids
+@node Axis and ticks, Curvilinear coordinates, Subplots, Advanced usage
+@subsection Axis and ticks
 
-MathGL library can draw not only the bounding box but also the axes, grids, labels and so on. The limits of axes and their origin (the point of intersection) are determined by function @code{Axis()}. Also you can use @code{XRange(), YRange(), ZRange()} functions (@pxref{Ranges (bounding box)}). Ticks on axis are specified by function @code{SetTicks} (@pxref{Ticks}). First argument the direction for each change will be applied. Second argument gives the step between ticks (if positive) or gives the number of ticks on the axis (if negative) or set to use logarithmic ticks (if zero). Third argument gives numbers of sub-ticks between ticks (default is zero). Last argument define the initial ticks position.
+MathGL library can draw not only the bounding box but also the axes, grids, labels and so on. The ranges of axes and their origin (the point of intersection) are determined by functions @code{SetRange()}, @code{SetRanges()}, @code{SetOrigin()} (see @ref{Ranges (bounding box)}). Ticks on axis are specified by function @code{SetTicks}, @code{SetTicksVal}, @code{SetTicksTime} (see @ref{Ticks}). But usually
 
 Function @code{Axis} draws axes. Its textual string shows in which directions the axis or axes will be drawn (by default @code{"xyz"}, function draws axes in all directions). Function @code{Grid} draws grid perpendicularly to specified directions. Example of axes and grid drawing is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->SubPlot(2,2,0);
-        gr->SetTicks('x', 0.4, 3);  // sets tick step to 0.5
-        gr->SetTicks('y', 0.4, 3);  // and draws 3 subticks
-        gr->Box();                  // should be after the ticks change
-        gr->Axis("xy");
-        gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Axis and grid");
-
-        gr->SetTicks('x');  gr->SetTicks('y'); // restore back
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(0,0,0));
-
-        gr->SubPlot(2,2,1);
-        gr->Rotate(60,40);
-        gr->Axis();
-        gr->Label('x',"x");
-        gr->Label('y',"y");
-        gr->Label('z',"z");
-        gr->Puts(mglPoint(0,0,1.5),"Axis and labels");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->SetTicks('x', 0.2); gr->SetTicks('y', 0.2);
-        gr->SetTicks('z', 0.2); // too low step of ticks
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(-1,-1,-1));
-        gr->Axis();
-        gr->Grid();
-        gr->Puts(mglPoint(0,0,1.5),"Shift origin and add grid");
-        gr->Puts(mglPoint(0,0,1.2),"(note, too many ticks)");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->SetTicks('x', -6);  // decrease the number of ticks
-        gr->SetTicks('y', -6);
-        gr->Axis("yz");
-        gr->Label('y',"Y axis",0);
-        gr->Label('z',"Z axis",0);
-        gr->Puts(mglPoint(0,0,1.5),"Remove X axis, and");
-        gr->Puts(mglPoint(0,0,1.2),"decrease number of ticks");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Title("Axis origin, Grid"); gr->SetOrigin(0,0);
+  gr->Axis(); gr->Grid(); gr->FPlot("x^3");
+
+  gr->SubPlot(2,2,1); gr->Title("2 axis");
+  gr->SetRanges(-1,1,-1,1); gr->SetOrigin(-1,-1,-1);  // first axis
+  gr->Axis(); gr->Label('y',"axis 1",0);  gr->FPlot("sin(pi*x)");
+  gr->SetRanges(0,1,0,1);   gr->SetOrigin(1,1,1);   // second axis
+  gr->Axis(); gr->Label('y',"axis 2",0);  gr->FPlot("cos(pi*x)");
+
+  gr->SubPlot(2,2,3); gr->Title("More axis");
+  gr->SetOrigin(NAN,NAN); gr->SetRange('x',-1,1);
+  gr->Axis(); gr->Label('x',"x",0); gr->Label('y',"y_1",0); gr->FPlot("x^2","k");
+  gr->SetRanges(-1,1,-1,1); gr->SetOrigin(-1.3,-1); // second axis
+  gr->Axis("y","r");  gr->Label('y',"#r{y_2}",0.2); gr->FPlot("x^3","r");
+
+  gr->SubPlot(2,2,2); gr->Title("4 segments, inverted axis");   gr->SetOrigin(0,0);
+  gr->InPlot(0.5,1,0.5,1);  gr->SetRanges(0,10,0,2);  gr->Axis();
+  gr->FPlot("sqrt(x/2)");   gr->Label('x',"W",1); gr->Label('y',"U",1);
+  gr->InPlot(0,0.5,0.5,1);  gr->SetRanges(1,0,0,2); gr->Axis("x");
+  gr->FPlot("sqrt(x)+x^3"); gr->Label('x',"\\tau",-1);
+  gr->InPlot(0.5,1,0,0.5);  gr->SetRanges(0,10,4,0);  gr->Axis("y");
+  gr->FPlot("x/4"); gr->Label('y',"L",-1);
+  gr->InPlot(0,0.5,0,0.5);  gr->SetRanges(1,0,4,0); gr->FPlot("4*x^2");
+  return 0;
+}
 @end verbatim
 
-This example shows the importance of the correct choosing of the number of ticks on axis. If tick step is too small then its text may overlap and becomes unreadable. This code has the example of @code{Label} function. It draws label for axis in specified direction. The text position on axis is specified by third argument of @code{Label} function. If it is positive then then text is drawn near the axis maximum, if negative then the same takes place near the minimum of axis, if zero - then at the center of axis.
+Note, that MathGL can draw not only single axis (which is default). But also several axis on the plot (see right plots). The idea is that the change of settings does not influence on the already drawn graphics. So, for 2-axes I setup the first axis and draw everything concerning it. Then I setup the second axis and draw things for the second axis. Generally, the similar idea allows one to draw rather complicated plot of 4 axis with different ranges (see bottom left plot).
 
 @float
-@image{../png/sample2, 7cm}
-@caption{Example of setting up axis range and axis ticks.}
+@image{../png/axis, 11cm}
+@caption{Example of axis.}
 @end float
 
-@c ------------------------------------------------------------------
-@node Curvilinear coordinates, Text printing example, Axis and grids, Advanced usage
-@subsection Curvilinear coordinates
+Another MathGL feature is fine ticks tunning. By default (if it is not changed by @code{SetTicks} function), MathGL try to adjust ticks positioning, so that they looks most human readable. At this, MathGL try to extract common factor for too large or too small axis ranges, as well as for too narrow ranges. Last one is non-common notation and can be disabled by @code{SetTuneTicks} function.
 
+Also, one can specify its own ticks with arbitrary labels by help of @code{SetTicksVal} function. Or one can set ticks in time format. In last case MathGL will try to select optimal format for labels with automatic switching between years, months/days, hours/minutes/seconds or microseconds. However, you can specify its own time representation using formats described in @url{http://www.manpagez.com/man/3/strftime/}. Most common variants are @samp{%X} for national representation of time, @samp{%x} for national representation of date, @samp{%Y} for year with century.
 
-Now let use curvilinear coordinates. In difference from other systems of plot creation, MathGL uses textual formulas for connection of the old (data) and new (output) coordinates. This allows one to plot in arbitrary coordinates. The following code plots the line @var{y}=0, @var{z}=0 in Cartesian, polar, parabolic and spiral coordinates:
+The sample code, demonstrated ticks feature is
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData x(50),y(50),z(50);
-        y.Fill(0.5,0.5);
-        x.Fill(-1,1);           // creates data arrays
-
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(-1,1,-1));
-        gr->dz = 0.5;           // sets tick step to 0.5
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(3,2,0); gr->Title("Usual axis");  gr->Axis();
+  gr->SubPlot(3,2,1); gr->Title("Too big/small range");
+  gr->SetRanges(-1000,1000,0,0.001);  gr->Axis();
+  gr->SubPlot(3,2,3); gr->Title("Too narrow range");
+  gr->SetRanges(100,100.1,10,10.01);  gr->Axis();
+  gr->SubPlot(3,2,4); gr->Title("Disable ticks tuning");
+  gr->SetTuneTicks(0);  gr->Axis();
+
+  gr->SubPlot(3,2,2); gr->Title("Manual ticks");  gr->SetRanges(-M_PI,M_PI, 0, 2);
+  float val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
+  gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
+  gr->Axis(); gr->Grid(); gr->FPlot("2*cos(x^2)^2", "r2");
+
+  gr->SubPlot(3,2,5); gr->Title("Time ticks");  gr->SetRange('x',0,3e5);
+  gr->SetTicksTime('x',0);  gr->Axis();
+  return 0;
+}
+@end verbatim
 
-        gr->SubPlot(2,2,0);
-        gr->Rotate(60,40);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Cartesian");
+@float
+@image{../png/ticks, 11cm}
+@caption{Features of axis ticks.}
+@end float
 
-        gr->SubPlot(2,2,1);
-        gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)",0);
-        gr->Rotate(60,40);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Cylindrical");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->SetFunc("2*y*x","y*y - x*x",0);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Parabolic");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)","x+z");
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Spiral");
-        return 0;
-    }
+The last sample I want to show in this subsection is Log-axis. From MathGL's point of vew, the log-axis is particular case of general curvilinear coordinates. So, we need first define new coordinates (see also @ref{Curvilinear coordinates}) by help of @code{SetFunc} or @code{SetCoor} functions. At this one should wary about proper axis range. So the code looks as following:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Semi-log axis");
+  gr->SetRanges(0.01,100,-1,1); gr->SetFunc("lg(x)","");
+  gr->Axis(); gr->Grid("xy","g"); gr->FPlot("sin(1/x)");
+  gr->Label('x',"x",0); gr->Label('y', "y = sin 1/x",0);
+
+  gr->SubPlot(2,2,1,"<_");  gr->Title("Log-log axis");
+  gr->SetRanges(0.01,100,0.1,100);  gr->SetFunc("lg(x)","lg(y)");
+  gr->Axis(); gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
+  gr->Label('y', "y = \\sqrt{1+x^2}",0);
+
+  gr->SubPlot(2,2,2,"<_");  gr->Title("Minus-log axis");
+  gr->SetRanges(-100,-0.01,-100,-0.1);  gr->SetFunc("-lg(-x)","-lg(-y)");
+  gr->Axis(); gr->FPlot("-sqrt(1+x^2)");
+  gr->Label('x',"x",0); gr->Label('y', "y = -\\sqrt{1+x^2}",0);
+
+  gr->SubPlot(2,2,3,"<_");  gr->Title("Log-ticks");
+  gr->SetRanges(0.1,100,0,100); gr->SetFunc("sqrt(x)","");
+  gr->Axis(); gr->FPlot("x");
+  gr->Label('x',"x",1); gr->Label('y', "y = x",0);
+  return 0;
+}
 @end verbatim
 
 @float
-@image{../png/sample3, 7cm}
-@caption{Example of curvilinear coordinates}
+@image{../png/loglog, 11cm}
+@caption{Features of axis ticks.}
 @end float
 
+You can see that MathGL automatically switch to log-ticks as we define log-axis formula (in difference from v.1.*). Moreover, it switch to log-ticks for any formula if axis range will be large enough (see right bottom plot). Another interesting feature is that you not necessary define usual log-axis (i.e. when coordinates are positive), but you can define ``minus-log'' axis when coordinate is negative (see left bottom plot).
 
 @c ------------------------------------------------------------------
-@node Text printing example, Animation, Curvilinear coordinates, Advanced usage
-@subsection Text printing example
+@node Curvilinear coordinates, Colorbars, Axis and ticks, Advanced usage
+@subsection Curvilinear coordinates
 
-MathGL prints text by vector font. There are functions for manual specifying of text position (like @code{Puts}) and for its automatic selection (like @code{Label}, @code{Legend} and so on). MathGL prints text always in specified position even if it lies outside the bounding box. The default size of font is specified by variables @var{FontSize} (@pxref{Font settings}). However, the actual size of output string depends on position of axes (depends on functions @code{SubPlot}, @code{InPlot}). The switching of the font style (italic, bold, wire and so on) can be done for the whole string (by function parameter) or inside the string. By default MathGL parses TeX-like commands for symbols and indexes (see @pxref{Font styles}). Example of MathGL font drawing is:
+As I noted in previous subsection, MathGL support curvilinear coordinates. In difference from other plotting programs and libraries, MathGL uses textual formulas for connection of the old (data) and new (output) coordinates. This allows one to plot in arbitrary coordinates. The following code plots the line @var{y}=0, @var{z}=0 in Cartesian, polar, parabolic and spiral coordinates:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        setlocale(LC_CTYPE, "ru_RU.cp1251");
-        gr->Puts(mglPoint(0,1),"Text can be in ASCII and in Unicode");
-        gr->Puts(mglPoint(0,0.6),"It can be \\wire{wire}, \\big{big} "
-            "or #r{colored}");
-        gr->Puts(mglPoint(0,0.2),"One can change style in string: "
-            "\\b{bold}, \\i{italic, \\b{both}}");
-        gr->Puts(mglPoint(0,-0.2),"Easy to \\a{overline} or "
-            "\\u{underline}");
-        gr->Puts(mglPoint(0,-0.6),"Easy to change indexes "
-            "^{up} _{down} @{center}");
-        gr->Puts(mglPoint(0,-1),"It parse TeX: \\int \\alpha \\cdot "
-            "\\sqrt3{sin(\\pi x)^2 + \\gamma_{i_k}} dx");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SetOrigin(-1,1,-1);
+
+  gr->SubPlot(2,2,0); gr->Title("Cartesian"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)",0);
+  gr->SubPlot(2,2,1); gr->Title("Cylindrical"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("2*y*x","y*y - x*x",0);
+  gr->SubPlot(2,2,2); gr->Title("Parabolic"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)","x+z");
+  gr->SubPlot(2,2,3); gr->Title("Spiral");  gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+  gr->SetFunc(0,0,0); // set to default Cartesian
+  return 0;
+}
 @end verbatim
 
 @float
-@image{../png/sample4, 7cm}
-@caption{Example of text printing with different font effects}
+@image{../png/curvcoor, 11cm}
+@caption{Example of curvilinear coordinates}
 @end float
 
-Another example demonstrate the features of TeX formula parsing.
+
+@c ------------------------------------------------------------------
+@node Colorbars, Ternary axis, Curvilinear coordinates, Advanced usage
+@subsection Colorbars
+
+MathGL handle colorbar as special kind of axis. So, most of functions for axis and ticks setup will work for colorbar too. Colorbars can be in log-scale, and generally as arbitrary function scale; common factor of colorbar labels can be separated; and so on.
+
+But of course, there are differences -- colorbars usually located out of bounding box. At this, colorbars can be at subplot boundaries (by default), or at bounding box (if symbol @samp{I} is specified). Colorbars can handle sharp colors. And they can be located at arbitrary position too. The sample code, which demonstrate colorbar features is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->Puts(mglPoint(0), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+"
-            "\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", 0, -4);
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Title("Colorbar out of box"); gr->Box();
+  gr->Colorbar("<");  gr->Colorbar(">");
+  gr->Colorbar("_");  gr->Colorbar("^");
+
+  gr->SubPlot(2,2,1); gr->Title("Colorbar near box");   gr->Box();
+  gr->Colorbar("<I"); gr->Colorbar(">I");
+  gr->Colorbar("_I"); gr->Colorbar("^I");
+
+  gr->SubPlot(2,2,2); gr->Title("manual colors");
+  mglData a,v;  mgls_prepare2d(&a,0,&v);
+  gr->Box();  gr->ContD(v,a);
+  gr->Colorbar(v,"<");  gr->Colorbar(v,">");
+  gr->Colorbar(v,"_");  gr->Colorbar(v,"^");
+
+  gr->SubPlot(2,2,3); gr->Title("log-scale");
+  gr->SetRange('c',0.01,1e3);
+  gr->Colorbar(">",0.5,0);  gr->Puts(mglPoint(0,1.2),"Normal scale");
+  gr->SetFunc("","","","lg(c)");
+  gr->Colorbar(">");    gr->Puts(mglPoint(1.3,1.2),"Log scale");
+  return 0;
+}
 @end verbatim
 
 @float
-@image{../png/samplee, 7cm}
-@caption{Example of TeX formula parsing}
+@image{../png/colorbar, 11cm}
+@caption{Example of colorbars}
 @end float
 
-Finally you can change font during execution.
+
+@c ------------------------------------------------------------------
+@node Ternary axis, Text features, Colorbars, Advanced usage
+@subsection Ternary axis
+
+There are another unusual axis types which are supported by MathGL. These are ternary and quaternary axis. Ternary axis is special axis of 3 coordinates @var{a}, @var{b}, @var{c} which satisfy relation @var{a}+@var{b}+@var{c}=1. Correspondingly, quaternary axis is special axis of 4 coordinates @var{a}, @var{b}, @var{c}, @var{d} which satisfy relation @var{a}+@var{b}+@var{c}+@var{d}=1.
+
+Generally speaking, only 2 of coordinates (3 for quaternary) are independent. So, MathGL just introduce some special transformation formulas which treat @var{a} as @samp{x}, @var{b} as @samp{y} (and @var{c} as @samp{z} for quaternary). As result, all plotting functions (curves, surfaces, contours and so on) work as usual, but in new axis. You should use @code{Ternary} function for switching to ternary/quaternary coordinates. The sample code is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        float h=1.1, d=0.25;
-        gr->LoadFont("STIX");       gr->Puts(mglPoint(0,h), "default font (STIX)");
-        gr->LoadFont("adventor");   gr->Puts(mglPoint(0,h-d), "adventor font");
-        gr->LoadFont("bonum");      gr->Puts(mglPoint(0,h-2*d), "bonum font");
-        gr->LoadFont("chorus");     gr->Puts(mglPoint(0,h-3*d), "chorus font");
-        gr->LoadFont("cursor");     gr->Puts(mglPoint(0,h-4*d), "cursor font");
-        gr->LoadFont("heros");      gr->Puts(mglPoint(0,h-5*d), "heros font");
-        gr->LoadFont("heroscn");    gr->Puts(mglPoint(0,h-6*d), "heroscn font");
-        gr->LoadFont("pagella");    gr->Puts(mglPoint(0,h-7*d), "pagella font");
-        gr->LoadFont("schola");     gr->Puts(mglPoint(0,h-8*d), "schola font");
-        gr->LoadFont("termes");     gr->Puts(mglPoint(0,h-9*d), "termes font");
-    }
+int sample(mglGraph *gr)
+{
+  gr->SetRanges(0,1,0,1,0,1);
+  mglData x(50),y(50),z(50),rx(10),ry(10), a(20,30);
+  a.Modify("30*x*y*(1-x-y)^2*(x+y<1)");
+  x.Modify("0.25*(1+cos(2*pi*x))");
+  y.Modify("0.25*(1+sin(2*pi*x))");
+  rx.Modify("rnd"); ry.Modify("(1-v)*rnd",rx);
+  z.Modify("x");
+
+  gr->SubPlot(2,2,0); gr->Title("Ordinary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('x',"B",1); gr->Label('y',"C",1); gr->Label('z',"Z",1);
+
+  gr->SubPlot(2,2,1); gr->Title("Ternary axis (x+y+t=1)");
+  gr->Ternary(1);
+  gr->Plot(x,y,"r2"); gr->Plot(rx,ry,"q^ ");  gr->Cont(a,"BbcyrR");
+  gr->Line(mglPoint(0.5,0), mglPoint(0,0.75), "g2");
+  gr->Axis(); gr->Grid("xyz","B;");
+  gr->Label('x',"B"); gr->Label('y',"C"); gr->Label('t',"A");
+
+  gr->SubPlot(2,2,2); gr->Title("Quaternary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Ternary(2);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('t',"A",1); gr->Label('x',"B",1);
+  gr->Label('y',"C",1); gr->Label('z',"D",1);
+
+  gr->SubPlot(2,2,3); gr->Title("Ternary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Ternary(1);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('t',"A",1); gr->Label('x',"B",1);
+  gr->Label('y',"C",1); gr->Label('z',"Z",1);
+  return 0;
+}
 @end verbatim
 
 @float
-@image{../png/fonts, 7cm}
-@caption{Example of font face changing.}
+@image{../png/ternary, 11cm}
+@caption{Example of colorbars}
 @end float
 
 @c ------------------------------------------------------------------
-@node Animation, , Text printing example, Advanced usage
-@subsection Animation
+@node Text features, Cutting sample, Ternary axis, Advanced usage
+@subsection Text features
 
-You can make animation by several methods in MathGL: by export in animated GIF, or by save each frame in separate file (usually JPEG) and convert these files into movie. Let me show both methods.
+MathGL prints text by vector font. There are functions for manual specifying of text position (like @code{Puts}) and for its automatic selection (like @code{Label}, @code{Legend} and so on). MathGL prints text always in specified position even if it lies outside the bounding box. The default size of font is specified by functions @var{SetFontSize*} (see @ref{Font settings}). However, the actual size of output string depends on subplot size (depends on functions @code{SubPlot}, @code{InPlot}). The switching of the font style (italic, bold, wire and so on) can be done for the whole string (by function parameter) or inside the string. By default MathGL parses TeX-like commands for symbols and indexes (see @ref{Font styles}).
 
-The simplest methods is making animated GIF. There are 3 steps: (1) open GIF file by @code{StartGIF()} function; (2) create the frames by calling @code{NewFrame()} before and @code{EndFrame()} after plotting; (3) close GIF by @code{CloseGIF()} function. So the simplest code for ``running'' sinusoid will look like this:
+Text can be printed as usual one (from left to right), along some direction (rotated text), or along a curve. Text can be printed on several lines, divided by new line symbol @samp{\n}.
+
+Example of MathGL font drawing is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData dat(100);
-        char str[32];
-        gr->StartGIF("sample.gif");
-        for(int i=0;i<100;i++)
-        {
-            gr->NewFrame();     // start frame
-            gr->Box();          // some plotting
-            sprintf(str,"sin(pi*x+%g*pi)",0.02*i);
-            dat.Modify(str);
-            gr->Plot(dat,"b");
-            gr->EndFrame();     // end frame
-        }
-        gr->CloseGIF();
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"");
+  gr->Putsw(mglPoint(0,1),L"Text can be in ASCII and in Unicode");
+  gr->Puts(mglPoint(0,0.6),"It can be \\wire{wire}, \\big{big} or #r{colored}");
+  gr->Puts(mglPoint(0,0.2),"One can change style in string: "
+  "\\b{bold}, \\i{italic, \\b{both}}");
+  gr->Puts(mglPoint(0,-0.2),"Easy to \\a{overline} or "
+  "\\u{underline}");
+  gr->Puts(mglPoint(0,-0.6),"Easy to change indexes ^{up} _{down} @{center}");
+  gr->Puts(mglPoint(0,-1),"It parse TeX: \\int \\alpha \\cdot "
+  "\\sqrt3{sin(\\pi x)^2 + \\gamma_{i_k}} dx");
+
+  gr->SubPlot(2,2,1,"");
+  gr->Puts(mglPoint(0,0.5), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", "@", -4);
+  gr->Puts(mglPoint(0,-0.5),"Text can be printed\non several lines");
+
+  gr->SubPlot(2,2,2,"");
+  mglData y;  mgls_prepare1d(&y);
+  gr->Box();  gr->Plot(y.SubData(-1,0));
+  gr->Text(y,"This is very very long string drawn along a curve",":k");
+  gr->Text(y,"Another string drawn above a curve","T:r");
+
+  gr->SubPlot(2,2,3,"");
+  gr->Line(mglPoint(-1,-1),mglPoint(1,-1),"rA");
+  gr->Puts(mglPoint(0,-1),mglPoint(1,-1),"Horizontal");
+  gr->Line(mglPoint(-1,-1),mglPoint(1,1),"rA");
+  gr->Puts(mglPoint(0,0),mglPoint(1,1),"At angle","@");
+  gr->Line(mglPoint(-1,-1),mglPoint(-1,1),"rA");
+  gr->Puts(mglPoint(-1,0),mglPoint(-1,1),"Vertical");
+  return 0;
+}
 @end verbatim
 
-The second way is saving each frame in separate file (usually JPEG) and later make the movie from them. MathGL have special function for saving frames -- it is @code{WriteFrame()}. This function save each frame with automatic name @samp{frame0001.jpg, frame0002.jpg} and so on. Here prefix @samp{frame} is defined by @var{PlotId} variable of @code{mglGraph} class. So the similar code will look like this:
+@float
+@image{../png/text, 11cm}
+@caption{Example of text printing}
+@end float
+
+@c ------------------------------------------------------------------
+@node Cutting sample, , Text features, Advanced usage
+@subsection Cutting sample
+
+The last common thing which I want to show in this section is how one can cut off points from plot. There are 4 mechanism for that.
+@itemize @bullet
+@item
+You can set one of coordinate to NAN value. All points with NAN values will be omitted.
+
+@item
+You can enable cutting at edges by @code{SetCut} function. As result all points out of bounding box will be omitted.
+
+@item
+You can set cutting box by @code{SetCutBox} function. All points inside this box will be omitted.
+
+@item
+You can define cutting formula by @code{SetCutOff} function. All points for which the value of formula is nonzero will be omitted. Note, that this is the slowest variant.
+@end itemize
+
+Below I place the code which demonstrate last 3 possibilities:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData dat(100);
-        char str[32];
-        for(int i=0;i<100;i++)
-        {
-            gr->NewFrame();     // start frame
-            gr->Box();          // some plotting
-            sprintf(str,"sin(pi*x+%g*pi)",0.02*i);
-            dat.Modify(str);
-            gr->Plot(dat,"b");
-            gr->EndFrame();     // end frame
-            gr->WriteFrame();   // save frame
-        }
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  mglData a,c,v(1); mgls_prepare2d(&a); mgls_prepare3d(&c); v.a[0]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("Cut on (default)");
+  gr->Rotate(50,60);  gr->Light(true);
+  gr->Box();  gr->Surf(a,"","zrange -1 0.5");
+
+  gr->SubPlot(2,2,1); gr->Title("Cut off");   gr->Rotate(50,60);
+  gr->Box();  gr->Surf(a,"","zrange -1 0.5; cut off");
+
+  gr->SubPlot(2,2,2); gr->Title("Cut in box");  gr->Rotate(50,60);
+  gr->SetCutBox(mglPoint(0,-1,-1), mglPoint(1,0,1.1));
+  gr->Alpha(true);  gr->Box();  gr->Surf3(c);
+  gr->SetCutBox(mglPoint(0), mglPoint(0));  // switch it off
+
+  gr->SubPlot(2,2,3); gr->Title("Cut by formula");  gr->Rotate(50,60);
+  gr->CutOff("(z>(x+0.5*y-1)^2-1) & (z>(x-0.5*y-1)^2-1)");
+  gr->Box();  gr->Surf3(c); gr->CutOff(""); // switch it off
+  return 0;
+}
 @end verbatim
 
-Created files can be converted to movie by help of a lot of programs. For example, you can use ImageMagic (command @samp{convert frame*.jpg movie.mpg}), MPEG library, GIMP and so on.
+@float
+@image{../png/cut, 11cm}
+@caption{Example of point cutting}
+@end float
+
 
-Finally, you can use @code{mgl2gif} tool for doing the same with MGL scripts (@pxref{Utilities}).
 
 @c ------------------------------------------------------------------
 @node Data handling, Data plotting, Advanced usage, Examples
@@ -584,90 +881,104 @@ Class @code{mglData} contains all functions for the data handling in MathGL (@px
 
 @menu
 * Array creation::
+* Linking array::
 * Change data::
+* User defined types::
 @end menu
 
 @c ------------------------------------------------------------------
 @node Array creation, Change data, , Data handling
 @subsection Array creation
 
+There are many ways in MathGL how data arrays can be created and filled.
+
 One can put the data in @code{mglData} instance by several ways. Let us do it for sinus function:
 @itemize @bullet
 @item
 one can create external array, fill it and put to @code{mglData} variable
 @verbatim
-    double *a = new double[50];
-    for(int i=0;i<50;i++)   a[i] = sin(M_PI*i/49.);
+  double *a = new double[50];
+  for(int i=0;i<50;i++)   a[i] = sin(M_PI*i/49.);
 
-    mglData y;
-    y.Set(a,50);
+  mglData y;
+  y.Set(a,50);
 @end verbatim
 
 @item
 another way is to create @code{mglData} instance of the desired size and then to work directly with data in this variable
 @verbatim
-    mglData y(50);
-    for(int i=0;i<50;i++)   y.a[i] = sin(M_PI*i/49.);
+  mglData y(50);
+  for(int i=0;i<50;i++)   y.a[i] = sin(M_PI*i/49.);
 @end verbatim
 
 @item
 next way is to fill the data in @code{mglData} instance by textual formula with the help of @code{Modify()} function
 @verbatim
-    mglData y(50);
-    y.Modify("sin(pi*x)");
+  mglData y(50);
+  y.Modify("sin(pi*x)");
 @end verbatim
 
 @item
 or one may fill the array in some interval and modify it later
 @verbatim
-    mglData y(50);
-    y.Fill(0,M_PI);
-    y.Modify("sin(u)");
+  mglData y(50);
+  y.Fill(0,M_PI);
+  y.Modify("sin(u)");
 @end verbatim
 
 @item
 finally it can be loaded from file
 @verbatim
-    FILE *fp=fopen("sin.dat","wt");   // create file first
-    for(int i=0;i<50;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
-    fclose(fp);
+  FILE *fp=fopen("sin.dat","wt");   // create file first
+  for(int i=0;i<50;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
+  fclose(fp);
 
-    mglData y("sin.dat");             // load it
+  mglData y("sin.dat");             // load it
 @end verbatim
+At this you can use textual or HDF files, as well as import values from bitmap image (PNG is supported right now).
 
 @item
 at this one can read only part of data
 @verbatim
-    FILE *fp-fopen("sin.dat","wt");   // create large file first
-    for(int i=0;i<70;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
-    fclose(fp);
+  FILE *fp-fopen("sin.dat","wt");   // create large file first
+  for(int i=0;i<70;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
+  fclose(fp);
 
-    mglData y;
-    y.Read("sin.dat",50);             // load it
+  mglData y;
+  y.Read("sin.dat",50);             // load it
 @end verbatim
 @end itemize
 
 Creation of 2d- and 3d-arrays is mostly the same. But one should keep in mind that class @code{mglData} uses flat data representation. For example, matrix 30*40 is presented as flat (1d-) array with length 30*40=1200 (nx=30, ny=40). The element with indexes @{i,j@} is a[i+nx*j]. So for 2d array we have:
 @verbatim
-    mglData z(30,40);
-    for(int i=0;i<30;i++)   for(int j=0;j<40;j++)
-        z.a[i+30*j] = sin(M_PI*i/29.)*sin(M_PI*j/39.);
+  mglData z(30,40);
+  for(int i=0;i<30;i++)   for(int j=0;j<40;j++)
+    z.a[i+30*j] = sin(M_PI*i/29.)*sin(M_PI*j/39.);
 @end verbatim
 or by using @code{Modify()} function
 @verbatim
-    mglData z(30,40);
-    z.Modify("sin(pi*x)*cos(pi*y)");
+  mglData z(30,40);
+  z.Modify("sin(pi*x)*cos(pi*y)");
 @end verbatim
 
-The only non-obvious thing here is using multidimensional arrays in C/C++, i.e. arrays defined like @code{float dat[40][30];}. Since, formaly this arrays element @code{dat[i]} can address the memory in arbitrary place you should use the proper function to convert such arrays to @code{mglData} object. For C++ this is functions like @code{mglData::Set(float **dat, int N1, int N2);}. For C this is functions like @code{mgl_data_set_float2(HMDT d, const float **dat, int N1, int N2);}. At this, you should keep in mind that @code{nx=N2} and @code{ny=N1} after conversion.
+The only non-obvious thing here is using multidimensional arrays in C/C++, i.e. arrays defined like @code{float dat[40][30];}. Since, formally these elements @code{dat[i]} can address the memory in arbitrary place you should use the proper function to convert such arrays to @code{mglData} object. For C++ this is functions like @code{mglData::Set(float **dat, int N1, int N2);}. For C this is functions like @code{mgl_data_set_float2(HMDT d, const float **dat, int N1, int N2);}. At this, you should keep in mind that @code{nx=N2} and @code{ny=N1} after conversion.
+
+@c ------------------------------------------------------------------
+@node Linking array, Change data, Array creation, Data handling
+@subsection Linking array
+
+Sometimes the data arrays are so large, that one don't need to copy its values to another array (i.e. into mglData).
+
+
+
 
 @c ------------------------------------------------------------------
-@node Change data, , Array creation, Data handling
+@node Change data, User defined types, Linking array, Data handling
 @subsection Change data
 
 MathGL has functions for data processing: differentiating, integrating, smoothing and so on (for more detail, @pxref{Data processing}). Let us consider some examples. The simplest ones are integration and differentiation. The direction in which operation will be performed is specified by textual string, which may contain symbols @samp{x}, @samp{y} or @samp{z}. For example, the call of @code{Diff("x")} will differentiate data along @samp{x} direction; the call of @code{Integral("xy")} perform the double integration of data along @samp{x} and @samp{y} directions; the call of @code{Diff2("xyz")} will apply 3d Laplace operator to data and so on. Example of this operations on 2d array a=x*y is presented in code:
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         mglData a(30,40);   a.Modify("x*y");
         gr->Axis(mglPoint(0,0,0),mglPoint(1,1,1));
@@ -694,7 +1005,7 @@ MathGL has functions for data processing: differentiating, integrating, smoothin
 
 Data smoothing (function @code{Smooth()}) is more interesting and important. This function has 2 main arguments: type of smoothing and its direction. Now 4 methods are supported: @code{SMOOTH_NONE} does nothing for delta=0 or approaches data to zero with the step delta, @code{SMOOTH_LINE_3} linear averaging by 3 points, @code{SMOOTH_LINE_5} linear averaging by 5 points, @code{SMOOTH_QUAD_5} quadratic averaging by 5 points. Let me demonstrate it for 1d case:
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         mglData y0(30),y1,y2,y3;
         y0.Modify("0.4*sin(2*pi*x)+0.3*cos(3*pi*x)-0.4*sin(4*pi*x)+0.2*rnd");
@@ -740,7 +1051,7 @@ Term ``1D data'' means that data depend on single index (parameter) like curve i
 
 Below I shall show the features of 1D plotting on base of @code{Plot()} function (see @ref{plot}). Let us start from sinus plot:
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         mglData y0(50);        y0.Modify("sin(pi*(2*x-1))");
         gr->SubPlot(2,2,0);
@@ -797,7 +1108,7 @@ Surfaces @code{Surf()} and other 2D plots (@pxref{2D plotting}) are drown the sa
 
 Now I shall show the example of a surface drawing. At first let us switch lightning on
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         gr->Light(true);       gr->Light(0,mglPoint(0,0,1));
 @end verbatim
@@ -845,7 +1156,7 @@ Note, that the previous color scheme is used in last plots because there are no
 
 Drawing of other 2D plots is analogous. The only peculiarity is the usage of flag @samp{#}. By default this flag switches on the drawing of a grid on plot (@code{Grid()} or @code{Mesh()} for plots in plain or in volume). However, for isosurfaces (including surfaces of rotation @code{Axial()}) this flag switches the  face drawing off. Figure becomes wired. The following code gives example of flag @samp{#} using (compare with normal function drawing as in its description):
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         gr->Alpha(true);       gr->Light(true);        gr->Light(0,mglPoint(0,0,1));
         mglData a(30,20);
@@ -874,7 +1185,7 @@ Drawing of other 2D plots is analogous. The only peculiarity is the usage of fla
 
 Drawing procedures for 3D plot looks similarly to 1D and 2D plots described above. There are 3 general types of 3D plots (@pxref{3D plotting}): (i) plots on slices or on projections, (ii) isosurfaces, (iii) cloud-like plots. Plots on slice are clear enough -- one specifies a slice (as its index or as coordinate value) and MathGL draws contour lines or density plot on slice plane. Isosurface gives more information. Isosurface is 3D analogue of the contour line @code{Cont()}. It shows the region where data array values exceed specified isosurface level. Plot becomes more informative if one adds transparency, lightning or sets color scheme depending on coordinates. Generalization of isosurface is the cloud-like plot. For this plot the darker color and less transparent regions correspond to higher values of data. Contrary, the regions with low values are transparent. For plotting of the phase of fields (or beams or pulses) one can use isosurface which transparency depends on the other data array (see function @code{Surf3A()}). As example of 3D data plots let us draw the Gaussian beam diffraction in space. Beam propagates along @var{x} axis:
 @verbatim
-    int sample(mglGraph *gr, void *)
+    int sample(mglGraph *gr)
     {
         gr->Alpha(true);    gr->Light(true);
         gr->Light(0,mglPoint(0,0,1));
@@ -948,160 +1259,12 @@ As example I shall show the variant of plot from @ref{Plots for 2D data} (grid d
 @section Dual samples
 
 @c ------------------------------------------------------------------
-@node More samples, C/Fortran interface, Dual samples, Examples
+@node More samples, Hints, Dual samples, Examples
 @section More samples
 
 
 @c ------------------------------------------------------------------
-@node C/Fortran interface, MathGL and PyQt, More samples, Examples
-@section C/Fortran interface
-
-The usage of pure C or Fortran or any similar interfaces (@pxref{C interface}) is practically identical to classes usage. But there are some differences. C functions must have argument HMGL (for graphics) and/or HMDT (for data arrays) which specifies the object for drawing or manipulating (changing). Fortran users may regard these variables as integer. So, firstly the user has to create this object by function mgl_create_*() and has to delete it after the using by function mgl_delete_*().
-
-Also, all arguments of C function have to be defined. So there are several functions with practically identical names doing practically the same. But some of them have simplified interface for the quick plotting and some of them have access to all plotting parameters for manual tunning.
-
-As an example of C function usage let me draw the plot from @ref{Plots for 2D data}. The C code which does it is shown below:
-@verbatim
-    #include <mgl/mgl_c.h>
-    int main()
-    {
-        HMGL gr = mgl_create_graph_zb(600, 400);
-        mgl_set_alpha(gr, true);
-        mgl_set_light(gr, true);
-        HMDT a = mgl_create_data_size(30,20,1);
-        mgl_data_modify(a,"0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))",0);
-
-        mgl_subplot(gr, 2,2,0);
-        mgl_rotate(gr, 40,60,0);
-        mgl_surf(gr,a,"BbcyrR#");
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,1);
-        mgl_rotate(gr, 40,60,0);
-        mgl_dens(gr,a,"BbcyrR#",NAN);
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,2);
-        mgl_rotate(gr, 40,60,0);
-        mgl_cont(gr,a,"BbcyrR#",7,NAN);
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,3);
-        mgl_rotate(gr, 40,60,0);
-        mgl_axial(gr,a,"BbcyrR#",3);
-        mgl_box(gr, true);
-
-        /* don't forgot to save graphics */
-        mgl_write_png(gr,"sample.png",0);
-        return 0;
-    }
-@end verbatim
-
-Practically the same simple to create a window. For example let rewrite the code from for window creation (@pxref{Using FLTK/GLUT window}):
-@verbatim
-    int sample(HMGL gr, void *)
-    {
-        mgl_rotate(gr,60,40,0);
-        mgl_box(gr,1);
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mgl_create_graph_fltk(sample, "MathGL examples", NULL);
-        mgl_fltk_run();
-        return 0;
-    }
-@end verbatim
-
-The Fortran code have some peculiarities. Exactly it not allow one to send arbitrary parameter (which was @code{NULL} in previous example) to function. This is limitation of Fortran language. So, the corresponding code will be @strong{NOT TESTED NOW!!!}:
-@verbatim
-    program TEST
-    integer x,f,func
-        call mgl_create_graph_fltk(sample, 'MathGL examples');
-        call mgl_fltk_run();
-    end program TEST
-
-    integer function sample(gr)
-    integer*8 gr
-        call mgl_rotate(gr,60,40,0);
-        call mgl_box(gr,1);
-        sample=0
-    return
-    end
-@end verbatim
-
-@c ------------------------------------------------------------------
-@node MathGL and PyQt, Hints, C/Fortran interface, Examples
-@section MathGL and PyQt
-
-Generally SWIG based classes (including the Python one) are the same as C++ classes. However, there are few tips for using MathGL with PyQt. Below I place a very simple python code which demonstrate how MathGL can be used with PyQt. This code is mostly written by Prof. Dr. Heino Falcke. You can just copy it to a file @code{mgl-pyqt-test.py} and execute it from python shell by command @code{execfile("mgl-pyqt-test.py")}
-
-@verbatim
-from PyQt4 import QtGui,QtCore
-from mathgl import *
-import sys
-app = QtGui.QApplication(sys.argv)
-qpointf=QtCore.QPointF()
-
-class hfQtPlot(QtGui.QWidget):
-    def __init__(self, parent=None):
-        QtGui.QWidget.__init__(self, parent)
-        self.img=(QtGui.QImage())
-    def setgraph(self,gr):
-        self.buffer='\t'
-        self.buffer=self.buffer.expandtabs(4*gr.GetWidth()*gr.GetHeight())
-        gr.GetBGRN(self.buffer,len(self.buffer))
-        self.img=QtGui.QImage(self.buffer, gr.GetWidth(),gr.GetHeight(),QtGui.QImage.Format_ARGB32)
-        self.update()
-    def paintEvent(self, event):
-        paint = QtGui.QPainter()
-        paint.begin(self)
-        paint.drawImage(qpointf,self.img)
-        paint.end()
-
-BackgroundColor=[1.0,1.0,1.0]
-size=100
-gr=mglGraph()
-y=mglData(size)
-#y.Modify("((0.7*cos(2*pi*(x+.2)*500)+0.3)*(rnd*0.5+0.5)+362.135+10000.)")
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-x=mglData(size)
-x.Modify("x^2");
-
-def plotpanel(gr,x,y,n):
-    gr.SubPlot(2,2,n)
-    gr.SetXRange(x)
-    gr.SetYRange(y)
-    gr.AdjustTicks()
-    gr.Axis()
-    gr.Box()
-    gr.Label("x","x-Axis",1)
-    gr.Label("y","y-Axis",1)
-    gr.ClearLegend()
-    gr.AddLegend("Legend: "+str(n),"k")
-    gr.Legend()
-    gr.Plot(x,y)
-
-
-gr.Clf(BackgroundColor[0],BackgroundColor[1],BackgroundColor[2])
-gr.SetPlotFactor(1.5)
-plotpanel(gr,x,y,0)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,1)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,2)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,3)
-
-gr.WritePNG("test.png","Test Plot")
-
-qw = hfQtPlot()
-qw.show()
-qw.setgraph(gr)
-qw.raise_()
-@end verbatim
-
-
-@c ------------------------------------------------------------------
-@node Hints, , MathGL and PyQt, Examples
+@node Hints, , More samples, Examples
 @section Hints
 
 In this section I have included some small hints and advices for the improving of the quality of plots and for the demonstration of some non-trivial features of MathGL library. In contrast to previous examples I showed mostly the idea but not the whole drawing function.
index c5546074897712d2bde873891b2fdca554911b76..b2bab3c105dc16e1bdc14b8e0754bf6d611c682a 100644 (file)
@@ -37,9 +37,9 @@ You should inherit yours class from @code{mglDraw} and re-implement one or both
 
 This class is derived from mglGraph class (@pxref{MathGL core}). It provide methods for handling window with MathGL graphics.
 
-@deftypefn {Constructor on @code{mglWindow}} {} mglWindow (@code{int} kind=@code{0}, @code{int} (*draw)(@code{HMGL} gr, @code{void *}p)=@code{NULL}, @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL})
-@deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{int} kind=@code{0}, @code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"})
-@deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{int} kind=@code{0}, @code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"})
+@deftypefn {Constructor on @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p)=@code{NULL}, @code{const char *}title=@code{"MathGL"}, @code{void *}par=@code{NULL}, @code{int} kind=@code{0})
+@deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{int} (*draw)(@code{mglGraph *}gr), @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
+@deftypefnx {Constructor on @code{mglWindow}} {} mglWindow (@code{mglDraw *}draw, @code{const char *}title=@code{"MathGL"}, @code{int} kind=@code{0})
 @deftypefnx {C function} @code{HMGL} mgl_create_graph_qt (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par)
 @deftypefnx {C function} @code{HMGL} mgl_create_graph_fltk (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par)
 @deftypefnx {C function} @code{HMGL} mgl_create_graph_glut (@code{int} (*draw)(@code{HMGL} gr, @code{void *}p), @code{const char *}title, @code{void *}par)
index 0d43264a6d934596dd35e0f400da03ea891d1581..7c51cc44c457b102931a557dd9423959e8592544 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -9,8 +9,7 @@
 
 ============= NEW  =============
 
-2. Export to X3D and VRML
-3. Sample for TriPlot (piramid) and QuadPlot (cube)
+1.Export to X3D and VRML
 
 ============= FOR V.2.1 ========
 
@@ -37,6 +36,7 @@
 19. line segment losses in EPS ???
 
 20. ReadHDF5 -- add string argument for handling lowest dimension (like complex numbers): "sum" - sum, "arg" - arg, "0...9" read slice 0...9, "abs" - sqrt(sum []^2)
+21. Change if possible long to size_t (be very accurate!!!)
 
 ============= UDAV =============
 
@@ -101,9 +101,7 @@ Remove other setting if data name is changed.
        * MathGL level -- pthread in mglData, ???
 12. Boxs() styles: '#' for wire, '@' for full box.
 13. Add mgl_label_xyz(), mgl_label_xy(), mgl_label_y(). Possible numbers are: "%x" for x-coor, "%y" for y-coor, "%z" for z-coor.
-15. Check mglData::Insert(): now copy values from original array (x[i] -> x[2*i], x[2*i+1], ...)
 16. Symbol '!' denote sharp colors even in 1d plots (like different colors for points)
-17. Check export to LaTeX.
 18. mglview can preview MGLD files too -- check it
 19. Handle mglBase::Stop everywhere
 20. Number of frames can be changed at reload + manual call of draw_func if number of frames is 0.
@@ -126,19 +124,18 @@ Remove other setting if data name is changed.
                1.5 Utilities
                1.6 Thanks
 
-       2. Examples
-               2.1 Basic usage (window; file; memory; QMathGL; Fl_MathGL; PyQt)
-               2.2 Advanced usage (subplots; axis; curv.coor; text)
-               2.3 Animation (win.stat; win.update; gif; jpeg/mpeg)
-               2.4 Data handling
-               2.5 1D data plotting
-               2.6 2D data plotting
-               2.7 3D data plotting
-               2.8 Dual data plotting
-               2.9 More samples
-               2.10 Multi-threading
-               2.11 Hints
-               2.12 FAQ
++      2. Examples
++              2.1 Basic usage (window; file; memory; QMathGL; Fl_MathGL; PyQt)
++              2.2 Advanced usage (subplots; axis; curv.coor; text)
+               2.3 Data handling
+               2.4 1D data plotting
+               2.5 2D data plotting
+               2.6 3D data plotting
+               2.7 Dual data plotting
+               2.8 More samples
+               2.9 Multi-threading
+               2.10 Hints
+               2.11 FAQ
 
 +      3. General concepts (class-diagram)
 +              3.1 Coordinate axes
index f4c73cb9411bd4667bc1217c29fd4428664c81eb..f3c52229e1d93988bf650c72d66bcea62ec32784 100644 (file)
@@ -70,7 +70,7 @@ int main(int narg, char **arg)
                if(j>0) fclose(fp);
        }
 #if defined(HAVE_FLTK) || defined(HAVE_QT)
-       mglWindow gr(kind, mgld?NULL:show ,j>0?arg[j]:"mglview");
+       mglWindow gr(mgld?NULL:show, j>0?arg[j]:"mglview", kind);
        if(mgld)
        {       gr.ImportMGLD(arg[j]);  gr.Update();    }
        gr.Run();
index b71c10b81fac9e637f5443878ee7f425b8c6505d..7ae750072a69d828b169c3dc16be3c043d6502eb 100644 (file)
@@ -122,7 +122,7 @@ void Fl_MathGL::update()
                gr->Alpha(flag&1);      gr->Light(flag&2);
                if(tet_val)     tet = tet_val->value();
                if(phi_val)     phi = phi_val->value();
-               gr->View(tet,phi);      gr->Zoom(x1,y1,x2,y2);  gr->Clf();
+               gr->Zoom(x1,y1,x2,y2);  gr->View(tet,phi);      gr->Clf();
                draw_func(gr, draw_par);        // drawing itself
                const char *buf = gr->Mess.c_str();
                if(*buf)        fl_message("%s",buf);
@@ -299,6 +299,7 @@ void mgl_norm_cb(Fl_Widget*, void* v)
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
        e->setoff_rotate();                     e->setoff_zoom();
        e->FMGL->tet_val->value(0);     e->FMGL->phi_val->value(0);
+       e->FMGL->set_zoom(0,0,1,1);
        e->update();
 }
 void mglCanvasFL::ToggleNo()   {       Fl::lock();     mgl_norm_cb(0,mgl);     Fl::unlock();   }
@@ -374,7 +375,7 @@ void mgl_su_cb(Fl_Widget*, void* v)
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
        mreal x1,x2,y1,y2,d;
        e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
-       d = (y2-y1)/3;  y1 += d;        y2 += d;
+       d = (y2-y1)/3;  y1 -= d;        y2 -= d;
        e->FMGL->set_zoom(x1,y1,x2,y2);
 }
 //-----------------------------------------------------------------------------
@@ -383,7 +384,7 @@ void mgl_sd_cb(Fl_Widget*, void* v)
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
        mreal x1,x2,y1,y2,d;
        e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
-       d = (y2-y1)/3;  y1 -= d;        y2 -= d;
+       d = (y2-y1)/3;  y1 += d;        y2 += d;
        e->FMGL->set_zoom(x1,y1,x2,y2);
 }
 //-----------------------------------------------------------------------------
@@ -392,7 +393,7 @@ void mgl_sr_cb(Fl_Widget*, void* v)
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
        mreal x1,x2,y1,y2,d;
        e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
-       d = (x2-x1)/3;  x1 += d;        x2 += d;
+       d = (x2-x1)/3;  x1 -= d;        x2 -= d;
        e->FMGL->set_zoom(x1,y1,x2,y2);
 }
 //-----------------------------------------------------------------------------
@@ -401,7 +402,7 @@ void mgl_sl_cb(Fl_Widget*, void* v)
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
        mreal x1,x2,y1,y2,d;
        e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
-       d = (x2-x1)/3;  x1 -= d;        x2 -= d;
+       d = (x2-x1)/3;  x1 += d;        x2 += d;
        e->FMGL->set_zoom(x1,y1,x2,y2);
 }
 //-----------------------------------------------------------------------------
index 803f100d709ad3bafe99cd259c0fb4d67978239c..c028167886ac80f4fbfdf8a4d57a2a052bf27159 100644 (file)
@@ -286,7 +286,7 @@ void QMathGL::mouseMoveEvent(QMouseEvent *ev)
                {
                        mreal ff = 1./sqrt(mreal(width()*height()));
                        mreal dx = (x0-xe)*ff*(x2-x1), dy = (y0-ye)*ff*(y2-y1);
-                       x1 -= dx;       x2 -= dx;       y1 += dy;       y2 += dy;
+                       x1 += dx;       x2 += dx;       y1 -= dy;       y2 -= dy;
                }
                x0 = xe;        y0 = ye;
                refresh();
@@ -610,7 +610,7 @@ void mglCanvasQT::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p
                a->connect(a, SIGNAL(lastWindowClosed()), a, SLOT(quit()));
        }
 
-       Wnd = new QMainWindow;  Wnd->resize(650,480);
+       Wnd = new QMainWindow;  Wnd->resize(850,680);
        Wnd->setWindowTitle(title);
        scroll = new QScrollArea(Wnd);
 
@@ -649,7 +649,6 @@ QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *tet, QSpinBox *phi
                o->addMenu(oo);         popup->addMenu(oo);
                oo = new QMenu(TR("&Export as 3D ..."),Wnd);
                oo->addAction(TR("X3D"), QMGL, SLOT(exportX3D()));
-               oo->addAction(TR("WRL"), QMGL, SLOT(exportWRL()));
                oo->addAction(TR("XYZ"), QMGL, SLOT(exportXYZ()));
                oo->addAction(TR("OBJ"), QMGL, SLOT(exportOBJ()));
                oo->addAction(TR("STL"), QMGL, SLOT(exportSTL()));
index 3e834096d127e2ead153079d7f2848eeae24d05c..7dc491947ca98ff171329a52a69209c4dff0b6a9 100644 (file)
@@ -181,7 +181,12 @@ uintptr_t mgl_create_graph_qt_(const char *title, int l)
 int mgl_qt_run_()      {       return mgl_qt_run();    }\r
 //-----------------------------------------------------------------------------\r
 int mgl_draw_class(mglBase *gr, void *p)\r
-{      mglGraph g(gr); return p ? ((mglDraw *)p)->Draw(&g) : 0;        }\r
+{\r
+       mglGraph g(gr);\r
+       mglWindow *w = (mglWindow *)p;  // so stupid way to save mglDraw class inheritance :(\r
+       return (w && w->dr) ? w->dr->Draw(&g) : 0;\r
+}\r
+//return p ? ((mglDraw *)p)->Draw(&g) : 0;     }\r
 void mgl_reload_class(void *p)\r
 {      if(p)   ((mglDraw *)p)->Reload();       }\r
 //-----------------------------------------------------------------------------\r
@@ -196,7 +201,7 @@ void *mgl_draw_calc(void *p)
 {\r
 #ifdef HAVE_PTHREAD\r
        ((mglDraw *)p)->Calc();\r
-#endif
+#endif\r
        return 0;\r
 }\r
 //-----------------------------------------------------------------------------\r