1 /***************************************************************************
2 * canvas.h is part of Math Graphic Library
3 * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Lesser General Public License as *
7 * published by the Free Software Foundation; either version 3 of the *
8 * License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Lesser General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifndef MGL_CANVAS_H
21 #define MGL_CANVAS_H
22 #include "mgl2/base.h"
23 //-----------------------------------------------------------------------------
24 struct GifFileType;
25 //-----------------------------------------------------------------------------
26 /// Structure for drawing axis and ticks
27 struct MGL_EXPORT mglAxis
28 {
mglAxismglAxis29 mglAxis() : dv(0),ds(0),d(0),ns(0), v0(0),v1(0),v2(0),o(NAN), f(0), ch(0), pos('t'),sh(0),inv(false),angl(NAN) {}
mglAxismglAxis30 mglAxis(const mglAxis &aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns), t(aa.t),fact(aa.fact),stl(aa.stl), dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt), ch(aa.ch), pos(aa.pos),sh(aa.sh),inv(aa.inv),angl(aa.angl) {}
31 #if MGL_HAVE_RVAL
mglAxismglAxis32 mglAxis(mglAxis &&aa) : dv(aa.dv),ds(aa.ds),d(aa.d),ns(aa.ns), t(aa.t),fact(aa.fact),stl(aa.stl), dir(aa.dir),a(aa.a),b(aa.b),org(aa.org), v0(aa.v0),v1(aa.v1),v2(aa.v2),o(aa.o), f(aa.f),txt(aa.txt), ch(aa.ch), pos(aa.pos),sh(aa.sh),inv(aa.inv),angl(aa.angl) {}
33 #endif
34
35 const mglAxis &operator=(const mglAxis &aa)
36 { dv=aa.dv; ds=aa.ds; d=aa.d; ns=aa.ns; t=aa.t; fact=aa.fact; stl=aa.stl;
37 dir=aa.dir; a=aa.a; b=aa.b; org=aa.org; v0=aa.v0; v1=aa.v1; v2=aa.v2; o=aa.o;
38 f=aa.f; txt=aa.txt; ch=aa.ch; pos=aa.pos; sh=aa.sh; inv=aa.inv; return aa; }
AddLabelmglAxis39 inline void AddLabel(const std::wstring &lbl, mreal v)
40 { if(mgl_isfin(v)) txt.push_back(mglText(L' '+lbl+L' ',v)); }
ClearmglAxis41 inline void Clear()
42 { dv=ds=d=v0=v1=v2=sh=0; o=NAN; ns=f=0; pos = 't'; inv=false;
43 fact.clear(); stl.clear(); t.clear(); txt.clear(); }
44
45 mreal dv,ds; ///< Actual step for ticks and subticks.
46 mreal d; ///< Step for axis ticks (if positive) or its number (if negative).
47 int ns; ///< Number of axis subticks.
48 std::wstring t; ///< Tick template (set "" to use default one ("%.2g" in simplest case))
49 std::wstring fact; ///< Factor which should be placed after number (like L"\pi")
50 std::string stl; ///< Tick styles (default is ""=>"3m")
51 mglPoint dir; ///< Axis direction
52 mglPoint a,b; ///< Directions of over axis
53 mglPoint org;
54 mreal v0; ///< Center of axis cross section
55 mreal v1; ///< Minimal axis range.
56 mreal v2; ///< Maximal axis range.
57 mreal o; ///< Point of starting ticks numbering (if NAN then Org is used).
58 int f; ///< Flag 0x1 - time, 0x2 - manual, 0x4 - fixed dv
59 std::vector<mglText> txt; ///< Axis labels
60 char ch; ///< Character of axis (like 'x','y','z','c')
61 char pos; ///< Text position ('t' by default, or 'T' for opposite)
62 mreal sh; ///< Extra shift of ticks and axis labels
63 bool inv; ///< Inverse automatic origin position
64 mreal angl; ///< Manual for ticks rotation (if not NAN)
65 };
66 //-----------------------------------------------------------------------------
67 class mglCanvas;
68 /// Structure for drawing region
69 struct MGL_EXPORT mglDrawReg
70 {
mglDrawRegmglDrawReg71 mglDrawReg() { memset(this,0,sizeof(mglDrawReg)); }
mglDrawRegmglDrawReg72 mglDrawReg(const mglDrawReg &aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2) {}
73 #if MGL_HAVE_RVAL
mglDrawRegmglDrawReg74 mglDrawReg(mglDrawReg &&aa) : PDef(aa.PDef),angle(aa.angle),ObjId(aa.ObjId),PenWidth(aa.PenWidth),pPos(aa.pPos) ,x1(aa.x1),x2(aa.x2),y1(aa.y1),y2(aa.y2) {}
75 #endif
copymglDrawReg76 inline void copy(const mglPrim &p)
77 { PDef = p.n3; pPos = p.s; ObjId = p.id; PenWidth=p.w; angle = p.angl;
78 if(p.type==2 || p.type==3) PDef = p.m; }
79 inline const mglDrawReg &operator=(const mglDrawReg &aa)
80 { PDef=aa.PDef; angle=aa.angle; ObjId=aa.ObjId; PenWidth=aa.PenWidth; pPos=aa.pPos; x1=aa.x1; x2=aa.x2; y1=aa.y1; y2=aa.y2; return aa; }
81 union
82 {
83 uint64_t PDef;
84 unsigned char m[8];
85 };
86 int angle; ///< mask rotation values in degrees
87 int ObjId;
88 mreal PenWidth, pPos;
89 int x1,x2,y1,y2;
90 void set(mglCanvas *gr, int nx, int ny, int m);
91 };
92 //-----------------------------------------------------------------------------
93 /// Structure contains everything for drawing
94 struct MGL_EXPORT mglDrawDat
95 {
mglDrawDatmglDrawDat96 mglDrawDat() {}
mglDrawDatmglDrawDat97 mglDrawDat(const mglDrawDat &aa) : Pnt(aa.Pnt),Prm(aa.Prm),Sub(aa.Sub),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt) {}
98 #if MGL_HAVE_RVAL
mglDrawDatmglDrawDat99 mglDrawDat(mglDrawDat &&aa) : Pnt(aa.Pnt),Prm(aa.Prm),Sub(aa.Sub),Ptx(aa.Ptx),Glf(aa.Glf),Txt(aa.Txt) {}
100 #endif
101 inline const mglDrawDat&operator=(const mglDrawDat &aa)
102 { Pnt=aa.Pnt; Prm=aa.Prm; Ptx=aa.Ptx; Glf=aa.Glf; Txt=aa.Txt; Sub=aa.Sub; return aa; }
103 mglStack<mglPnt> Pnt; ///< Internal points
104 mglStack<mglPrim> Prm; ///< Primitives (lines, triangles and so on) -- need for export
105 std::vector<mglBlock> Sub; ///< InPlot regions
106 std::vector<mglText> Ptx; ///< Text labels for mglPrim
107 std::vector<mglGlyph> Glf; ///< Glyphs data
108 std::vector<mglTexture> Txt; ///< Pointer to textures
109 };
110 #if defined(_MSC_VER)
111 MGL_EXTERN template class MGL_EXPORT std::vector<mglDrawDat>;
112 #endif
113 //-----------------------------------------------------------------------------
114 union mglRGBA { uint32_t c; unsigned char r[4]; };
115 //-----------------------------------------------------------------------------
116 /// Class contains all functionality for creating different mathematical plots
117 class MGL_EXPORT mglCanvas : public mglBase
118 {
119 friend struct mglPrim;
120 friend struct mglDrawReg;
121 public:
122 using mglBase::Light;
123
124 mglCanvas(int w=800, int h=600);
125 virtual ~mglCanvas();
126
127 /// Set default parameter for plotting
128 void DefaultPlotParam();
129
130 /// Set angle of view indepently from mglCanvas::Rotate()
131 virtual void View(mreal tetx,mreal tetz,mreal tety=0);
132 /// Zoom in or zoom out (if Zoom(0, 0, 1, 1)) a part of picture
133 virtual void Zoom(mreal x1, mreal y1, mreal x2, mreal y2);
134 /// Restore image after View() and Zoom()
Restore()135 inline void Restore() { Zoom(0,0,1,1); }
136
137 /// Clear transformation matrix.
138 inline void Identity(bool rel=false) { InPlot(0,1,0,1,rel); }
139 inline void Identity(mglMatrix &M, bool rel=false) { InPlot(M,0,1,0,1,rel); }
140 /// Push transformation matrix into stack
141 void Push();
142 /// Set PlotFactor
SetPlotFactor(mreal val)143 inline void SetPlotFactor(mreal val)
144 { if(val<=0) {B.pf=1.55; set(MGL_AUTO_FACTOR);} else {B.pf=val; clr(MGL_AUTO_FACTOR);} }
145 /// Get PlotFactor
GetPlotFactor()146 inline mreal GetPlotFactor() { return B.pf; }
147 /// Pop transformation matrix from stack
148 void Pop();
149 /// Clear up the frame
150 virtual void Clf(mglColor back=NC);
151 virtual void Clf(const char *col);
152
153 /// Put further plotting in cell of stick rotated on angles tet, phi
154 void StickPlot(int num, int i, mreal tet, mreal phi);
155 /// Put further plotting in cell of stick sheared on sx, sy
156 void ShearPlot(int num, int i, mreal sx, mreal sy, mreal xd, mreal yd);
157 /// Put further plotting in some region of whole frame surface.
158 inline void InPlot(mreal x1,mreal x2,mreal y1,mreal y2,bool rel=true)
159 { InPlot(B,x1,x2,y1,y2,rel); }
160 void InPlot(mreal x1,mreal x2,mreal y1,mreal y2, const char *style);
161 void InPlot(mglMatrix &M,mreal x1,mreal x2,mreal y1,mreal y2,bool rel=true);
162 /// Add title for current subplot/inplot
163 void Title(const char *title,const char *stl="#",mreal size=-2);
164 void Title(const wchar_t *title,const char *stl="#",mreal size=-2);
165 /// Set aspect ratio for further plotting.
166 void Aspect(mreal Ax,mreal Ay,mreal Az);
167 /// Shear a further plotting.
168 void Shear(mreal Sx,mreal Sy);
169 /// Rotate a further plotting.
170 void Rotate(mreal TetX,mreal TetZ,mreal TetY=0);
171 /// Rotate a further plotting around vector {x,y,z}.
172 void RotateN(mreal Tet,mreal x,mreal y,mreal z);
173 /// Set perspective (in range [0,1)) for plot. Set to zero for switching off. Return the current perspective.
174 void Perspective(mreal a, bool req=true)
175 { if(req) persp = Bp.pf = a; else Bp.pf = persp?persp:fabs(a); }
176 /// Save parameters of current inplot
SaveInPlot()177 inline void SaveInPlot()
178 { sB=B; sW=inW, sH=inH, sZ=ZMin, sX=inX, sY=inY, sFF=font_factor; }
179 /// Use saved parameters as current inplot
LoadInPlot()180 inline void LoadInPlot()
181 { B=sB; inW=sW, inH=sH, ZMin=sZ, inX=sX, inY=sY, font_factor=sFF; }
182
183 /// Set size of frame in pixels. Normally this function is called internaly.
184 virtual void SetSize(int w,int h,bool clf=true);
185 /// Get ratio (mreal width)/(mreal height).
186 mreal GetRatio() const MGL_FUNC_PURE;
187 /// Get bitmap data prepared for saving to file
188 virtual unsigned char **GetRGBLines(long &w, long &h, unsigned char *&f, bool alpha=false);
189 /// Get RGB bitmap of current state image.
190 virtual const unsigned char *GetBits();
191 /// Get RGBA bitmap of background image.
GetBackground()192 const unsigned char *GetBackground() { return GB; };
193 /// Get RGBA bitmap of current state image.
GetRGBA()194 const unsigned char *GetRGBA() { Finish(); return G4; }
195 /// Get width of the image
GetWidth()196 int GetWidth() const { return Width; }
197 /// Get height of the image
GetHeight()198 int GetHeight() const { return Height; }
199 /// Combine plots from 2 canvases. Result will be saved into this.
200 void Combine(const mglCanvas *gr);
201 /// Set boundary box for export graphics into 2D file formats
202 void SetBBox(int x1=0, int y1=0, int x2=-1, int y2=-1)
203 { BBoxX1=x1; BBoxY1=y1; BBoxX2=x2; BBoxY2=y2; }
204
205 /// Rasterize current plot and set it as background image
206 void Rasterize();
207 /// Load image for background from file (basic variant)
208 void LoadBackground(const char *fname, double alpha=1);
209 /// Load image for background from file.
210 /** Parameter 'how' can be:
211 * 'a' for filling current subplot only;
212 * 's' for spline-based resizing;
213 * 'f' for fixing aspect ratio at resizing;
214 * 'c' for centering image;
215 * 't' for tessellate image. */
216 void LoadBackground(const char *fname, const char *how, double alpha=1);
217 /// Fill background image by specified color
218 void FillBackground(const mglColor &cc);
219
GetDelay()220 inline mreal GetDelay() const { return Delay; }
SetDelay(mreal d)221 inline void SetDelay(mreal d) { Delay=d; }
222
223 /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys}
224 mglPoint CalcXYZ(int xs, int ys, bool real=false) const MGL_FUNC_PURE;
225 /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z}
226 void CalcScr(mglPoint p, int *xs, int *ys) const;
227 mglPoint CalcScr(const mglPoint &p) const;
228 /// Set object/subplot id
SetObjId(long id)229 inline void SetObjId(long id) { ObjId = id; }
230 /// Get object id
GetObjId(long xs,long ys)231 inline int GetObjId(long xs,long ys) const
232 { long i=xs+Width*ys; return (i>=0 && i<Width*Height)?OI[i]:-1; }
233 /// Get subplot id
234 int GetSplId(long xs,long ys) const MGL_FUNC_PURE;
235 /// Check if there is active point or primitive (n=-1)
236 int IsActive(int xs, int ys,int &n);
237
238 /// Create new frame.
239 virtual int NewFrame();
240 /// Finish frame drawing
241 virtual void EndFrame();
242 /// Get the number of created frames
GetNumFrame()243 inline int GetNumFrame() const { return CurFrameId; }
244 /// Reset frames counter (start it from zero)
245 virtual void ResetFrames();
246 /// Delete primitives for i-th frame
247 virtual void DelFrame(long i);
248 /// Get drawing data for i-th frame.
249 void GetFrame(long i);
250 /// Set drawing data for i-th frame. This work as EndFrame() but don't add frame to GIF image.
251 virtual void SetFrame(long i);
252 /// Add drawing data from i-th frame to the current drawing
253 void ShowFrame(long i);
254 /// Clear list of primitives for current drawing
255 void ClearFrame();
256
257 /// Start write frames to cinema using GIF format
258 void StartGIF(const char *fname, int ms=100);
259 /// Stop writing cinema using GIF format
260 void CloseGIF();
261 /// Finish plotting. Normally this function is called internaly.
262 virtual void Finish();
263 /// Export points and primitives in file using MGLD format
264 bool ExportMGLD(const char *fname, const char *descr=0);
265 /// Import points and primitives from file using MGLD format
266 bool ImportMGLD(const char *fname, bool add=false);
267 /// Export in JSON format suitable for later drawing by JavaScript
268 bool WriteJSON(const char *fname, bool force_zlib=false);
269 std::string GetJSON();
270
271 /// Set the transparency type
SetTranspType(int val)272 inline void SetTranspType(int val)
273 { Flag=(Flag&(~3)) + (val&3); SetAxisStl(val==2?"w-":"k-"); }
274 /// Set the fog distance or switch it off (if d=0).
275 virtual void Fog(mreal d, mreal dz=0.25);
276 /// Switch on/off the specified light source.
277 virtual void Light(int n, bool enable);
278 /// Add a light source.
279 virtual void AddLight(int n,mglPoint r, mglPoint d, char c='w', mreal bright=0.5, mreal ap=0);
280 inline void AddLight(int n,mglPoint d, char c='w', mreal bright=0.5, mreal ap=0)
281 { AddLight(n,mglPoint(NAN),d,c,bright,ap); }
282
283 /// Set ticks position and text (\n separated). Use n=0 to disable this feature.
284 void SetTicksVal(char dir, const char *lbl, bool add=false);
285 void SetTicksVal(char dir, HCDT v, const char *lbl, bool add=false);
286 void SetTicksVal(char dir, HCDT v, const char **lbl, bool add=false);
287 void SetTicksVal(char dir, const wchar_t *lbl, bool add=false);
288 void SetTicksVal(char dir, HCDT v, const wchar_t *lbl, bool add=false);
289 void SetTicksVal(char dir, HCDT v, const wchar_t **lbl, bool add=false);
290 /// Add manual tick at given position. Use "" to disable this feature.
291 void AddTick(char dir, double val, const char *lbl);
292 void AddTick(char dir, double val, const wchar_t *lbl);
293
294 /// Set templates for ticks
295 void SetTickTempl(char dir, const wchar_t *t);
296 void SetTickTempl(char dir, const char *t);
297 /// Set time templates for ticks
298 void SetTickTime(char dir, mreal d=0, const char *t="");
299 /// Set the ticks parameters
300 void SetTicks(char dir, mreal d=0, int ns=0, mreal org=NAN, const wchar_t *lbl=0);
301 /// Auto adjust ticks
302 void AdjustTicks(const char *dir="xyzc", bool force=false, const std::string &stl="");
303 /// Tune ticks
304 inline void SetTuneTicks(int tune, mreal pos=1.15)
305 { TuneTicks = tune; FactorPos = pos; }
306 /// Set ticks styles
307 void SetAxisStl(const char *stl="k", const char *tck=0, const char *sub=0);
308 /// Set ticks length
309 void SetTickLen(mreal tlen, mreal stt=1.);
310
311 /// Draws bounding box outside the plotting volume with color c.
312 void Box(const char *col=0, bool ticks=true);
313 /// Draw axises with ticks in directions determined by string parameter dir.
314 void Axis(const char *dir="xyzt", const char *stl="", const char *opt="");
315 /// Draw grid lines perpendicular to direction determined by string parameter dir.
316 void Grid(const char *dir="xyzt",const char *pen="B-", const char *opt="");
317 /// Print the label text for axis dir.
318 void Label(char dir, const char *text, mreal pos=0, const char *opt="");
319 void Labelw(char dir, const wchar_t *text, mreal pos=0, const char *opt="");
320
321 /// Draw colorbar at edge of axis
322 void Colorbar(const char *sch=0);
323 void Colorbar(const char *sch, mreal x, mreal y, mreal w, mreal h);
324 /// Draw colorbar at edge of axis for manual colors
325 void Colorbar(HCDT v, const char *sch=0);
326 void Colorbar(HCDT v, const char *sch, mreal x, mreal y, mreal w, mreal h);
327
328 /// Draw legend of accumulated strings at position (x, y) by font with size
329 inline void Legend(mreal x, mreal y, const char *font="#", const char *opt="")
330 { Legend(Leg,x,y,font,opt); }
331 /// Draw legend of accumulated strings by font with size
332 inline void Legend(int where=0x3, const char *font="#", const char *opt="")
333 { Legend(Leg,(where&1)?1:0,(where&2)?1:0,font,opt); }
334 /// Draw legend of accumulated strings by font with size
335 inline void Legend(const std::vector<mglText> &leg, int where=3, const char *font="#", const char *opt="")
336 { Legend(leg,(where&1)?1:0,(where&2)?1:0,font,opt); }
337 /// Draw legend strings text at position (x, y) by font with size
338 void Legend(const std::vector<mglText> &leg, mreal x, mreal y, const char *font="#", const char *opt="");
339 /// Number of marks in legend sample
340 inline void SetLegendMarks(int num=1) { LegendMarks = num>0?num:1; }
341
342 /// Draw table for values val along given direction with row labels text at given position
343 void Table(mreal x, mreal y, HCDT val, const wchar_t *text, const char *fnt, const char *opt);
344
345 void StartAutoGroup (const char *);
346 void EndGroup();
347 /// Set extra shift for tick and axis labels
SetTickShift(mglPoint p)348 inline void SetTickShift(mglPoint p)
349 { ax.sh = p.x; ay.sh = p.y; az.sh = p.z; ac.sh = p.c; }
350 /// Get rotation angle for glyph
351 float GetGlyphPhi(const mglPnt &q, float phi);
352
353 // Following arrays are open for advanced users only. It is not recommended to change them directly
354 float *Z; ///< Height for given level in Z-direction (size 3*width*height)
355 unsigned char *C; ///< Picture for given level in Z-direction (size 3*4*width*height)
356 int *OI; ///< ObjId arrays (size width*height)
357 /// Plot point p with color c
358 void pnt_plot(long x,long y,mreal z,const unsigned char c[4], int obj_id);
359 void pnt_fast(long x,long y,mreal z,const unsigned char c[4], int obj_id);
360 /// preparing primitives for 2d export or bitmap drawing (0 default, 1 for 2d vector, 2 for 3d vector)
361 void PreparePrim(int fast);
GetPntCol(long i)362 inline uint32_t GetPntCol(long i) const { return pnt_col[i]; }
363 inline uint32_t GetPrmCol(long i, bool sort=true) const { return GetColor(GetPrm(i, sort)); }
364 /// Set the size of semi-transparent area around lines, marks, ...
SetPenDelta(float d)365 inline void SetPenDelta(float d) { pen_delta = 1.5*fabs(d); }
366
367 protected:
368 mreal Delay; ///< Delay for animation in seconds
369 // NOTE: Z should be float for reducing space and for compatibility reasons
370 unsigned char *G4; ///< Final picture in RGBA format. Prepared in Finish().
371 unsigned char *G; ///< Final picture in RGB format. Prepared in Finish().
372 unsigned char *GB; ///< Background picture in RGBA format.
373 std::vector<mglDrawDat> DrwDat; ///< Set of ALL drawing data for each frames
374
375 int LegendMarks; ///< Number of marks in the Legend
376 unsigned char BDef[4]; ///< Background color
377 mglAxis ax,ay,az,ac;///< Axis parameters
378
379 int TuneTicks; ///< Draw tuned ticks with extracted common component
380 mreal FactorPos; ///< Position of axis ticks factor (0 at Min, 1 at Max, 1.1 is default)
381 mreal TickLen; ///< Length of tiks (subticks length is sqrt(1+st_t)=1.41... times smaller)
382 char AxisStl[32]; ///< Axis line style. Default is "k"
383 char TickStl[32]; ///< Tick line style. Default is "k"
384 char SubTStl[32]; ///< Subtick line style. Default is "k"
385 mreal st_t; ///< Subtick-to-tick ratio (ls=lt/sqrt(1+st_t)). Default is 1.
386
387 int CurFrameId; ///< Number of automaticle created frames
388 int Width; ///< Width of the image
389 int Height; ///< Height of the image
390 int Depth; ///< Depth of the image
391 mreal inW, inH; ///< Width and height of last InPlot
392 mreal inX, inY; ///< Coordinates of last InPlot
393 mglLight light[10]; ///< Light sources
394 mreal FogDist; ///< Inverse fog distance (fog ~ exp(-FogDist*Z))
395 mreal FogDz; ///< Relative shift of fog
396
GetAxis(unsigned ch)397 inline mglAxis &GetAxis(unsigned ch)
398 { mglAxis *aa[3]={&ax,&ay,&az}; ch-='x'; return ch<3?*(aa[ch]):ac; }
GetFormula(unsigned ch)399 inline HMEX GetFormula(unsigned ch)
400 { HMEX aa[3]={fx,fy,fz}; ch-='x'; return ch<3?aa[ch]:fa; }
401 /// Auto adjust ticks
402 void AdjustTicks(mglAxis &aa, bool ff);
403 /// Prepare labels for ticks
404 void LabelTicks(mglAxis &aa);
405 /// Draw axis
406 void DrawAxis(mglAxis &aa, int text=1, char arr=0,const char *stl="",mreal angl=NAN);
407 /// Draw axis grid lines
408 void DrawGrid(mglAxis &aa, bool at_tick=false);
409 /// Update axis ranges
UpdateAxis()410 inline void UpdateAxis()
411 { ax.v0=Org.x; ay.v0=Org.y; az.v0=Org.z; ac.v0=Org.c;
412 ax.v1=Min.x; ay.v1=Min.y; az.v1=Min.z; ac.v1=Min.c;
413 ax.v2=Max.x; ay.v2=Max.y; az.v2=Max.z; ac.v2=Max.c; }
414
415 /// Clear ZBuffer only
416 void ClfZB(bool force=false);
417 /// Scale coordinates and cut off some points
418 bool ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan=true) const;
419 void LightScale(const mglMatrix *M); ///< Additionally scale positions of light sources
420 void LightScale(const mglMatrix *M, mglLight &l); ///< Additionally scale positions of light
421 /// Push drawing data (for frames only). NOTE: can be VERY large
422 long PushDrwDat();
423 /// Retur color for primitive depending lighting
424 uint32_t GetColor(const mglPrim &p) const MGL_FUNC_PURE;
425
426 mreal GetOrgX(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.x (parse NAN value)
427 mreal GetOrgY(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.y (parse NAN value)
428 mreal GetOrgZ(char dir, bool inv=false) const MGL_FUNC_PURE; ///< Get Org.z (parse NAN value)
429
430 void mark_plot(long p, char type, mreal size=1);
431 void arrow_plot(long p1, long p2, char st);
432 void line_plot(long p1, long p2);
433 void trig_plot(long p1, long p2, long p3);
434 void quad_plot(long p1, long p2, long p3, long p4);
435 void Glyph(mreal x, mreal y, mreal f, int style, long icode, mreal col);
436 void smbl_plot(long p1, char id, double size);
437 mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal col=-('k'), bool rot=true);
438
439 void add_prim(mglPrim &a); ///< add primitive to list
440 void arrow_draw(const mglPnt &p1, const mglPnt &p2, char st, mreal size, const mglDrawReg *d);
441 virtual void mark_draw(const mglPnt &p, char type, mreal size, mglDrawReg *d);
442 virtual void line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d);
443 virtual void trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d);
444 virtual void quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d);
445 virtual void pnt_draw(const mglPnt &p, const mglDrawReg *d);
446 void arrow_draw(long n1, long n2, char st, float ll);
447 void arrow_plot_3d(long n1, long n2, char st, float ll);
448 void glyph_draw(const mglPrim &P, mglDrawReg *d);
449 void glyph_draw_new(const mglPrim &P, mglDrawReg *d);
450 bool IsSame(const mglPrim &pr,mreal wp,mglColor cp,int st);
451
452 // check if visible
453 bool trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const;
454 bool quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const;
455
456 // functions for glyph drawing
457 virtual void glyph_fill(mreal phi, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);
458 void glyph_wire(mreal phi, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);
459 void glyph_line(mreal phi, const mglPnt &p, mreal f, bool solid, const mglDrawReg *d);
460
461 // restore normalized coordinates from screen ones
462 mglPoint RestorePnt(mglPoint ps, bool norm=false) const MGL_FUNC_PURE;
463
464 // functions for multi-threading
465 void pxl_pntcol(long id, long n, const void *);
466 void pxl_combine(long id, long n, const void *);
467 void pxl_memcpy(long id, long n, const void *);
468 void pxl_backgr(long id, long n, const void *);
469 void pxl_primdr(long id, long n, const void *);
470 void pxl_dotsdr(long id, long n, const void *);
471 void pxl_primpx(long id, long n, const void *);
472 void pxl_transform(long id, long n, const void *);
473 void pxl_setz(long id, long n, const void *);
474 void pxl_setz_adv(long id, long n, const void *);
475 void pxl_other(long id, long n, const void *p);
476 /// Put drawing from other mglCanvas (for multithreading, like subplots)
477 void PutDrawReg(mglDrawReg *d, const mglCanvas *gr);
478
479 private:
mglCanvas(const mglCanvas &)480 mglCanvas(const mglCanvas &){} // copying is not allowed
481 const mglCanvas &operator=(const mglCanvas &t){return t;} // copying is not allowed
482
483 mglMatrix sB; // parameters of saved inplot
484 mreal sW, sH, sZ, sX, sY, sFF;
485
486 uint32_t *pnt_col;
487 // mreal _tetx,_tety,_tetz; // extra angles
488 std::vector<mglMatrix> stack; ///< stack for transformation matrices
489 GifFileType *gif;
490 mreal fscl,ftet; ///< last scale and rotation for glyphs
491 long forg; ///< original point (for directions)
492 size_t grp_counter; ///< Counter for StartGroup(); EndGroup();
493 mglMatrix Bt; ///< temporary matrix for text
494 float pen_delta; ///< delta pen width (dpw) -- the size of semi-transparent region for lines, marks, ...
495
496 /// Draw generic colorbar
497 void colorbar(HCDT v, const mreal *s, int where, mreal x, mreal y, mreal w, mreal h, bool text);
498 /// Draw labels for ticks
499 void DrawLabels(mglAxis &aa, bool inv=false, const mglMatrix *M=0);
500 /// Get label style
501 char GetLabelPos(mreal c, long kk, mglAxis &aa);
502 /// Draw tick
503 void tick_draw(mglPoint o, mglPoint d1, mglPoint d2, int f);
504 mreal FindOptOrg(char dir, int ind) const MGL_FUNC_PURE;
505 /// Transform mreal color and alpha to bits format
506 void col2int(const mglPnt &p, unsigned char *r, int obj_id) const;
507 /// Combine colors in 2 plane.
508 void combine(unsigned char *c1, const unsigned char *c2) const;
509 /// Fast drawing of line between 2 points
510 void fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d);
511
512 /// Additionally scale points p for positioning in image
513 void PostScale(const mglMatrix *M, mglPoint &p) const;
514 /// Scale points p for projection to the face number nface in image
515 long ProjScale(int nface, long p, bool text=false);
516 /// Set coordinate and add the point, return its id
517 long setPp(mglPnt &q, const mglPoint &p);
518
519 // fill pixel for given primitive
520 void mark_pix(long i,long j,const mglPnt &p, char type, mreal size, mglDrawReg *d);
521 void arrow_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, char st, mreal size, const mglDrawReg *d);
522 void line_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglDrawReg *d);
523 void trig_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d);
524 void quad_pix(long i,long j,const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d);
525 void glyph_pix(long i,long j,const mglPrim &P, mglDrawReg *d);
526 void pnt_pix(long i,long j,const mglPnt &p, const mglDrawReg *d);
527 void glyph_fpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);
528 void glyph_wpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, const mglGlyph &g, const mglDrawReg *d);
529 void glyph_lpix(long i,long j,const mglMatrix *M, const mglPnt &p, mreal f, bool solid, const mglDrawReg *d);
530 };
531 //-----------------------------------------------------------------------------
532 struct mglThreadG
533 {
534 mglCanvas *gr; // grapher
535 void (mglCanvas::*f)(long i, long n, const void *);
536 unsigned id; // thread id
537 long n; // total number of iteration
538 const void *p; // external parameter
539 };
540 /// Start several thread for the task
541 void mglStartThread(void (mglCanvas::*func)(long i, long n), mglCanvas *gr, long n);
542 //-----------------------------------------------------------------------------
get_persp(float pf,float z,float Depth)543 inline mreal get_persp(float pf, float z, float Depth)
544 //{ return (1-pf)/(1-pf*z/Depth); }
545 { return (1-pf/1.37)/(1-pf*z/Depth); }
get_pfact(float pf,float Depth)546 inline mreal get_pfact(float pf, float Depth)
547 //{ return pf/(1-pf)/Depth; }
548 { return pf/(1-pf/1.37)/Depth; }
549 //-----------------------------------------------------------------------------
550 #endif
551