1 /***************************************************************************
2 * base.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_BASE_H_
21 #define _MGL_BASE_H_
22 //#if !defined(_MSC_VER) && !defined(__BORLANDC__)
23 #include "mgl2/abstract.h"
24
25 #ifdef __cplusplus
26
27 #if (MGL_HAVE_PTHREAD|MGL_HAVE_PTHR_WIDGET)
28 #include <pthread.h>
29 #endif
30
31 #if MGL_HAVE_PTHREAD
32 #define MGL_PUSH(a,v,m) {pthread_mutex_lock(&m); a.push_back(v); pthread_mutex_unlock(&m);}
33 #else
34 #define MGL_PUSH(a,v,m) a.push_back(v);
35 #endif
36
37 #if MGL_HAVE_PTHREAD
38 #define MGL_PUSHs(func,m) {pthread_mutex_lock(&m); func; pthread_mutex_unlock(&m);}
39 #else
40 #define MGL_PUSHs(func,m) {func;}
41 #endif
42 //-----------------------------------------------------------------------------
mgl_d(mreal v,mreal v1,mreal v2)43 inline mreal mgl_d(mreal v,mreal v1,mreal v2) { return v2!=v1?(v-v1)/(v2-v1):NAN; }
44 //-----------------------------------------------------------------------------
45 mglPoint GetX(HCDT x, int i, int j, int k=0);
46 mglPoint GetY(HCDT y, int i, int j, int k=0);
47 mglPoint GetZ(HCDT z, int i, int j, int k=0);
48 //-----------------------------------------------------------------------------
49 /// Class for replacement of std::vector
50 // NOTE memcpy is used --> no memory allocation in T
51 template <class T> class mglStack
52 {
53 T **dat;
54 unsigned MGL_PB; ///< size of buffer (real size is 2^pb == 1L<<pb).
55 /** NOTE This limit the number of maximal points and primitives as (1<<MGL_PB)^2,
56 * i.e. as 10^12 for MGL_PB=20 or 4*10^9 for MGL_PB=16. See mgl_bsize().*/
57 size_t nb; ///< used blocks
58 size_t n; ///< used cells
59 void *mutex;
60 public:
mglStack(const mglStack<T> & st)61 mglStack(const mglStack<T> &st)
62 { mutex = 0; n=0; nb=1; MGL_PB = mgl_bsize(0);
63 dat = new T*[(size_t)1<<MGL_PB];
64 *dat = new T[(size_t)1<<MGL_PB]; reserve(st.n);
65 for(size_t i=0;i<nb;i++)
66 memcpy(dat[i],st.dat[i],((size_t)1<<MGL_PB)*sizeof(T));
67 n=st.n; }
mglStack()68 mglStack()
69 { mutex = 0; n=0; nb=1; MGL_PB = mgl_bsize(0);
70 dat = new T*[(size_t)1<<MGL_PB];
71 *dat = new T[(size_t)1<<MGL_PB]; }
~mglStack()72 ~mglStack() { clear(); delete [](*dat); delete []dat; }
set_mutex(void * mtx)73 inline void set_mutex(void *mtx) { mutex=mtx; }
allocate(size_t num)74 inline size_t allocate(size_t num)
75 { reserve(num); size_t r=n; n+=num; return r; }
reserve(size_t num)76 void reserve(size_t num)
77 {
78 num = num?num+n:n+1; // final required size
79 if(num>(nb<<MGL_PB))
80 {
81 num = 1 + (num>>MGL_PB);
82 for(;nb<num;nb++) dat[nb] = new T[(size_t)1<<MGL_PB];
83 }
84 }
clear()85 void clear()
86 {
87 if(mutex) mgl_mutex_lock(mutex);
88 for(size_t i=1;i<nb;i++) delete [](dat[i]);
89 n=0; nb=1;
90 if(mutex) mgl_mutex_unlock(mutex);
91 }
92 T &operator[](size_t i)
93 { size_t d=i>>MGL_PB; return dat[d][i-(d<<MGL_PB)]; }
94 const T &operator[](size_t i) const
95 { size_t d=i>>MGL_PB; return dat[d][i-(d<<MGL_PB)]; }
push_back(const T & t)96 void push_back(const T &t)
97 {
98 if(n>=(nb<<MGL_PB)) reserve(1);
99 size_t d=n>>MGL_PB; dat[d][n-(d<<MGL_PB)] = t; n++;
100 }
push_back(size_t num,const T * t)101 void push_back(size_t num, const T *t)
102 {
103 if(n+num>=(nb<<MGL_PB)) reserve(num);
104 for(size_t i=0;i<num;i++)
105 { size_t d=n>>MGL_PB; dat[d][n-(d<<MGL_PB)] = t[i]; n++; }
106 }
size()107 size_t size() const { return n; }
108 const mglStack<T> &operator=(const mglStack<T> &st)
109 {
110 clear(); reserve(st.n);
111 for(size_t i=0;i<nb;i++)
112 memcpy(dat[i],st.dat[i],((size_t)1<<MGL_PB)*sizeof(T));
113 n = st.n; return st;
114 }
115 };
116 //-----------------------------------------------------------------------------
117 /// Structure for transformation matrix
118 struct MGL_EXPORT mglMatrix
119 {
120 float x,y,z,pf;
121 float b[9];
122 bool norot; // flag to disable pnts rotation
mglMatrixmglMatrix123 mglMatrix() { clear(); }
mglMatrixmglMatrix124 mglMatrix(const mglMatrix &aa) : x(aa.x),y(aa.y),z(aa.z),pf(aa.pf),norot(aa.norot) { memcpy(b,aa.b,9*sizeof(float)); }
125 void Rotate(mreal tetz,mreal tetx,mreal tety);
126 void RotateN(mreal Tet,mreal x,mreal y,mreal z);
clearmglMatrix127 inline void clear() { x=y=z=pf=0; memset(b,0,9*sizeof(float)); b[0]=b[4]=b[8]=1; norot=false; }
128 inline const mglMatrix &operator=(const mglMatrix &a)
129 { x=a.x; y=a.y; z=a.z; pf=a.pf; memcpy(b,a.b,9*sizeof(float)); norot=false; return a; }
130 };
131 inline bool operator==(const mglMatrix &a, const mglMatrix &b)
132 { return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)==0)&&!memcmp(b.b,a.b,9*sizeof(float));}
133 inline bool operator!=(const mglMatrix &a, const mglMatrix &b)
134 { return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z)+(a.pf-b.pf)*(a.pf-b.pf)!=0)||memcmp(b.b,a.b,9*sizeof(float)); }
135 //-----------------------------------------------------------------------------
136 /// Structure for simplest primitives
137 struct MGL_EXPORT mglPrim // NOTE: use float for reducing memory size
138 {
139 // NOTE: n4 is used as mark; n3 -- as pen style for type=0,1,4
140 // NOTE: n3 is used as position of txt,font in Ptxt for type=6
141 long n1,n2,n3,n4; ///< coordinates of corners
142 short type; ///< primitive type (0-point, 1-line, 2-trig, 3-quad, 4-glyph, 6-text)
143 short angl; ///< rotation angle for mask
144 int id; ///< object id
145 float z; ///< z-position
146 float w; ///< width (if applicable) or ftet
147 union
148 {
149 struct
150 {
151 float s; ///< size (if applicable) or fscl
152 float p;
153 };
154 uint64_t m;
155 };
mglPrimmglPrim156 mglPrim():n1(0),n2(0),n3(0),n4(0),type(0),angl(0),id(0),z(0),w(0),m(0) {}
mglPrimmglPrim157 explicit mglPrim(int t):n1(0),n2(0),n3(0),n4(0),type(t),angl(0),id(0),z(0),w(0),m(0) {}
mglPrimmglPrim158 mglPrim(const mglPrim &aa) : n1(aa.n1),n2(aa.n2),n3(aa.n3),n4(aa.n4),type(aa.type),angl(aa.angl),id(aa.id),z(aa.z),w(aa.w),m(aa.m) {}
159 const mglPrim &operator=(const mglPrim &aa)
160 { n1=aa.n1; n2=aa.n2; n3=aa.n3; n4=aa.n4; type=aa.type; angl=aa.angl; id=aa.id; z=aa.z; w=aa.w; m=aa.m; return aa; }
161 };
162 bool operator<(const mglPrim &a,const mglPrim &b);
163 bool operator>(const mglPrim &a,const mglPrim &b);
164 //-----------------------------------------------------------------------------
165 /// Structure for light source
166 struct MGL_EXPORT mglLight
167 {
mglLightmglLight168 mglLight():a(0),b(0),n(false) {}
mglLightmglLight169 mglLight(const mglLight &aa) : d(aa.d),r(aa.r),q(aa.q),p(aa.p),c(aa.c),a(aa.a),b(aa.b),n(aa.n) {}
170 const mglLight &operator=(const mglLight &aa)
171 { d=aa.d; r=aa.r; q=aa.q; p=aa.p; c=aa.c; a=aa.a; b=aa.b; n=aa.n; return aa; }
172
173 mglPoint d; ///< Direction of light sources
174 mglPoint r; ///< Position of light sources (NAN for infinity)
175 mglPoint q; ///< Actual position of light sources (filled by LightScale() function)
176 mglPoint p; ///< Actual direction of light sources (filled by LightScale() function)
177 mglColor c; ///< Color of light sources
178 float a; ///< Aperture of light sources
179 float b; ///< Brightness of light sources
180 bool n; ///< Availability of light sources
181 };
182 //-----------------------------------------------------------------------------
183 /// Structure for inplot
184 struct MGL_EXPORT mglBlock
185 {
186 long n1,n2,n3,n4; ///< coordinates of corners {n1=x1,n2=x2,n3=y1,n4=y2}
187
188 mglLight light[10]; ///< Light sources
189 float AmbBr; ///< Default ambient light brightness
190 float DifBr; ///< Default diffusive light brightness
191 mglMatrix B; ///< Transformation matrix
192 int id; ///< object id
193
mglBlockmglBlock194 mglBlock():n1(0),n2(0),n3(0),n4(0),AmbBr(0.5),DifBr(0.5),id(0) {}
mglBlockmglBlock195 mglBlock(const mglBlock &aa) { memcpy(this, &aa, sizeof(mglBlock)); }
196 const mglBlock &operator=(const mglBlock &aa)
197 { n1=aa.n1; n2=aa.n2; n3=aa.n3; n4=aa.n4; for(int i=0;i<10;i++) light[i]=aa.light[i];
198 AmbBr=aa.AmbBr; DifBr=aa.DifBr; B=aa.B; id=aa.id; return aa; }
199 };
200 //-----------------------------------------------------------------------------
201 /// Structure for group of primitives
202 struct MGL_EXPORT mglGroup
203 {
204 std::vector<long> p; ///< list of primitives (not filled!!!)
205 int Id; ///< Current list of primitives
206 std::string Lbl; ///< Group label
IdmglGroup207 mglGroup(const char *lbl="", int id=0) : Id(id), Lbl(lbl) {}
mglGroupmglGroup208 mglGroup(const mglGroup &aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl) {}
209 #if MGL_HAVE_RVAL
mglGroupmglGroup210 mglGroup(mglGroup &&aa) : p(aa.p),Id(aa.Id),Lbl(aa.Lbl) {}
211 #endif
212 inline const mglGroup &operator=(const mglGroup &aa) { Lbl = aa.Lbl; Id = aa.Id; p = aa.p; return aa; }
213 };
214 //-----------------------------------------------------------------------------
215 /// Structure for text label
216 struct MGL_EXPORT mglText
217 {
218 std::wstring text;
219 std::string stl;
220 float val;
textmglText221 mglText(const wchar_t *txt=L"", const char *fnt="", float v=0) : text(txt), stl(fnt), val(v) {}
textmglText222 mglText(const std::wstring &txt, float v=0): text(txt), val(v) {}
mglTextmglText223 mglText(const mglText &aa) : text(aa.text),stl(aa.stl),val(aa.val) {}
224 #if MGL_HAVE_RVAL
mglTextmglText225 mglText(mglText &&aa) : text(aa.text),stl(aa.stl),val(aa.val) {}
226 #endif
227 const mglText&operator=(const mglText &aa) { text=aa.text; stl=aa.stl; val=aa.val; return aa; }
228 };
229 //-----------------------------------------------------------------------------
230 /// Structure for internal point representation
231 struct MGL_EXPORT mglPnt // NOTE: use float for reducing memory size
232 {
233 union { float dat[15]; struct {
234 float x,y,z; // coordinates
235 float u,v,w; // normales
236 float r,g,b,a; // RGBA color
237 float xx,yy,zz; // original coordinates
238 float c,ta; // index in color scheme
239 }; };
240 int sub; // subplot id and rotation information (later will be in subplot)
xmglPnt241 mglPnt(float X=0, float Y=0, float Z=0, float U=0, float V=0, float W=0, float R=0, float G=0, float B=0, float A=0, short s=0) :x(X),y(Y),z(Z),u(U),v(V),w(W),r(R),g(G),b(B),a(A),xx(X),yy(Y),zz(Z),c(0),ta(0),sub(s) {}
mglPntmglPnt242 mglPnt(const mglPnt &aa) : sub(aa.sub) { memcpy(dat,aa.dat,15*sizeof(float)); }
243 inline const mglPnt&operator=(const mglPnt &aa) { sub=aa.sub; memcpy(dat,aa.dat,15*sizeof(float)); return aa; }
samemglPnt244 inline bool same(const mglPnt &p, mreal d) const { return fabs(x-p.x)<d && fabs(y-p.y)<d; }
245 };
246 inline mglPnt operator+(const mglPnt &a, const mglPnt &b)
247 //{ mglPnt p; for(long i=0;i<10;i++) p.dat[i] = a.dat[i]+b.dat[i]; p.sub=a.sub; return p; }
248 { return mglPnt(a.x+b.x,a.y+b.y,a.z+b.z, a.u+b.u,a.v+b.v,a.w+b.w, a.r+b.r,a.g+b.g,a.b+b.b,a.a+b.a, a.sub); }
249 inline mglPnt operator-(const mglPnt &a, const mglPnt &b)
250 //{ mglPnt p; for(long i=0;i<10;i++) p.dat[i] = a.dat[i]-b.dat[i]; p.sub=a.sub; return p; }
251 { return mglPnt(a.x-b.x,a.y-b.y,a.z-b.z, a.u-b.u,a.v-b.v,a.w-b.w, a.r-b.r,a.g-b.g,a.b-b.b,a.a-b.a, a.sub); }
252 inline mglPnt operator*(const mglPnt &a, float b)
253 //{ mglPnt p; for(long i=0;i<10;i++) p.dat[i] = a.dat[i]*b; p.sub=a.sub; return p; }
254 { return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b, a.sub); }
255 inline mglPnt operator*(float b, const mglPnt &a)
256 //{ mglPnt p; for(long i=0;i<10;i++) p.dat[i] = a.dat[i]*b; p.sub=a.sub; return p; }
257 { return mglPnt(a.x*b,a.y*b,a.z*b, a.u*b,a.v*b,a.w*b, a.r*b,a.g*b,a.b*b,a.a*b, a.sub); }
258 //-----------------------------------------------------------------------------
259 /// Structure for glyph representation
260 struct MGL_EXPORT mglGlyph
261 { // NOTE nt<0 is used to set char id for user-defined glyphs
262 long nt, nl; ///< number of triangles and lines
263 short *trig, *line; ///< vertexes of triangles and lines
264
mglGlyphmglGlyph265 mglGlyph():nt(0),nl(0),trig(0),line(0) {}
mglGlyphmglGlyph266 mglGlyph(const mglGlyph &a):nt(0),nl(0),trig(0),line(0) { *this=a; }
mglGlyphmglGlyph267 mglGlyph(long Nt, long Nl):nt(0),nl(0),trig(0),line(0) { Create(Nt,Nl); }
~mglGlyphmglGlyph268 ~mglGlyph() { if(trig) delete []trig; if(line) delete []line; }
269
270 void Create(long Nt, long Nl); ///< Allocate memory for given sizes
271 void Load(wchar_t id, const char *fname); ///< Load glyph 'id' from TTF/OTF file 'fname'
272 bool operator==(const mglGlyph &g) const MGL_FUNC_PURE;
273 inline bool operator!=(const mglGlyph &g) const MGL_FUNC_PURE
274 { return !(*this==g); }
275 inline const mglGlyph &operator=(const mglGlyph &a)
276 { Create(a.nt, a.nl);
277 if(a.trig) memcpy(trig, a.trig, 6*nt*sizeof(short));
278 if(a.line) memcpy(line, a.line, 2*nl*sizeof(short));
279 return a; }
280 };
281 //-----------------------------------------------------------------------------
282 #define MGL_TEXTURE_COLOURS 512
283 /// Structure for texture (color scheme + palette) representation
284 struct MGL_EXPORT mglTexture
285 {
286 mglColor *col; ///< Colors itself
287 long n; ///< Number of initial colors along u
288 mglColor *c0; ///< Initial colors
289 float *val; ///< Initial color positions
290
291 char Sch[260]; ///< Color scheme used
292 int Smooth; ///< Type of texture (smoothing and so on)
293 float Alpha; ///< Transparency
294
mglTexturemglTexture295 mglTexture():n(0),c0(NULL),val(NULL),Smooth(0),Alpha(1)
296 { col = new mglColor[MGL_TEXTURE_COLOURS]; }
297 mglTexture(const char *cols, int smooth=0,mreal alpha=1):n(0),c0(NULL),val(NULL)
298 { col = new mglColor[MGL_TEXTURE_COLOURS]; Set(cols,smooth,alpha); }
mglTexturemglTexture299 mglTexture(const mglTexture &aa) : n(aa.n),Smooth(aa.Smooth),Alpha(aa.Alpha)
300 { col = new mglColor[MGL_TEXTURE_COLOURS]; memcpy(Sch,aa.Sch,260);
301 memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));
302 c0 = new mglColor[2*aa.n]; memcpy(c0,aa.c0,2*aa.n*sizeof(mglColor));
303 val = new float[aa.n]; memcpy(val,aa.val,aa.n*sizeof(float)); }
304 #if MGL_HAVE_RVAL
mglTexturemglTexture305 mglTexture(mglTexture &&aa) : n(aa.n),c0(aa.c0),val(aa.val),Smooth(aa.Smooth),Alpha(aa.Alpha)
306 { col = aa.col; memcpy(Sch,aa.Sch,260); aa.col=aa.c0=0; aa.val=0; }
307 #endif
~mglTexturemglTexture308 ~mglTexture() { if(col) delete []col; Clear(); }
ClearmglTexture309 void Clear()
310 { if(c0) { delete []c0; delete []val; }
311 n=0; c0=NULL; val=NULL; }
312 void Set(const char *cols, int smooth=0,mreal alpha=1);
313 void Set(HCDT val, const char *cols);
314 void GetC(mreal u,mreal v,mglPnt &p) const;
315 mglColor GetC(mreal u,mreal v=0) const MGL_FUNC_PURE;
IsSamemglTexture316 inline bool IsSame(const mglTexture &t) const
317 { return n==t.n && !memcmp(col,t.col,MGL_TEXTURE_COLOURS*sizeof(mglColor)); }
318 void GetRGBA(unsigned char *f) const;
319 void GetRGBAPRC(unsigned char *f) const;
320 void GetRGBAOBJ(unsigned char *f) const; // Export repeating border colors, since OBJ by default wraps textures and we need an extra boundary to work around implementation quirks
321 inline const mglTexture &operator=(const mglTexture &aa)
322 { n=aa.n; Smooth=aa.Smooth; Alpha=aa.Alpha;
323 memcpy(col,aa.col,MGL_TEXTURE_COLOURS*sizeof(mglColor));
324 memcpy(Sch,aa.Sch,260); return aa; }
325 };
326 //-----------------------------------------------------------------------------
327 const mglColor NC(-1,-1,-1);
328 const mglColor BC( 0, 0, 0);
329 const mglColor WC( 1, 1, 1);
330 const mglColor RC( 1, 0, 0);
331 //-----------------------------------------------------------------------------
332 /// Structure active points
333 struct MGL_EXPORT mglActivePos
334 {
335 int x,y; ///< coordinates of active point
336 int id; ///< object id for active point
337 int n; ///< position of active point in command (object id)
338 };
339 //-----------------------------------------------------------------------------
340 #if defined(_MSC_VER)
341 MGL_EXTERN template class MGL_EXPORT mglStack<mglPnt>;
342 MGL_EXTERN template class MGL_EXPORT mglStack<mglPrim>;
343 MGL_EXTERN template class MGL_EXPORT std::vector<mglGroup>;
344 MGL_EXTERN template class MGL_EXPORT std::vector<mglText>;
345 MGL_EXTERN template class MGL_EXPORT std::vector<mglTexture>;
346 MGL_EXTERN template class MGL_EXPORT std::vector<mglGlyph>;
347 MGL_EXTERN template class MGL_EXPORT std::vector<mglBlock>;
348 MGL_EXTERN template class MGL_EXPORT std::vector<mglMatrix>;
349 MGL_EXTERN template class MGL_EXPORT mglStack<mglActivePos>;
350 #endif
351 //-----------------------------------------------------------------------------
352 /// Base class for canvas which handle all basic drawing
353 class MGL_EXPORT mglBase
354 {
355 public:
356 mglBase();
357 virtual ~mglBase();
358
359 mglPoint Min; ///< Lower edge of bounding box for graphics.
360 mglPoint Max; ///< Upper edge of bounding box for graphics.
361 mreal ZMin; ///< Adjusted minimal z-value 1D plots
362 std::string Mess; ///< Buffer for receiving messages
363 int ObjId; ///< object id for mglPrim
364 int HighId; ///< object id to be highlited
365 std::vector<mglGroup> Grp; ///< List of groups with names -- need for export
366 mglStack<mglActivePos> Act; ///< Position of active points
367 std::string PlotId; ///< Id of plot for saving filename (in GLUT window for example)
368 int BBoxX1, BBoxY1, BBoxX2, BBoxY2; ///< BBox region for exporting 2d graphics
369 std::vector<mglGlyph> UserGlf; ///< User-defined glyphs data
370
371 mreal CDef; ///< Default (current) color in texture
372 mreal AlphaDef; ///< Default value of alpha channel (transparency)
373 mreal BarWidth; ///< Relative width of rectangles in Bars().
374 int MeshNum; ///< Set approximate number of lines in Mesh and Grid. By default (=0) it draw all lines.
375 int FaceNum; ///< Set approximate number of visible faces and lines. By default (=0) it draw everything.
376 char Arrow1, Arrow2;///< Style of arrows at end and at start of curve
377 long InUse; ///< Smart pointer (number of users)
378 uint32_t Flag; ///< Flags for controlling drawing
379 mreal size_opt; ///< Value of size option (or NAN if not specified)
380
get(uint32_t fl)381 inline bool get(uint32_t fl) const { return Flag&fl; }
set(uint32_t fl)382 inline void set(uint32_t fl) { Flag |= fl; }
clr(uint32_t fl)383 inline void clr(uint32_t fl) { Flag &=~fl; }
set(bool v,uint32_t fl)384 inline void set(bool v,uint32_t fl) { Flag = v ? Flag|fl : Flag&(~fl); }
385
386 /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image!
387 inline void ZoomAxis(const mglPoint &p1=mglPoint(0,0,0,0), const mglPoint &p2=mglPoint(1,1,1,1)) { AMin = p1; AMax = p2; }
388 /// Set values of mglGraph::Min and mglGraph::Max
389 inline void SetRanges(mreal x1, mreal x2, mreal y1, mreal y2, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0)
390 { SetRanges(mglPoint(x1,y1,z1,c1),mglPoint(x2,y2,z2,c2)); }
391 void SetRanges(const mglPoint &v1, const mglPoint &v2);
392 /// Set values of mglGraph::Cmin and mglGraph::Cmax as minimal and maximal values of data a
393 void CRange(HCDT a, bool add = false, mreal fact=0);
394 void CRange(mreal v1,mreal v2,bool add=false);
395 /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
396 void XRange(HCDT a, bool add = false, mreal fact=0);
397 void XRange(mreal v1,mreal v2,bool add=false);
398 /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
399 void YRange(HCDT a, bool add = false, mreal fact=0);
400 void YRange(mreal v1,mreal v2,bool add=false);
401 /// Set values of mglGraph::Min.x and mglGraph::Max.x as minimal and maximal values of data a
402 void ZRange(HCDT a, bool add = false, mreal fact=0);
403 void ZRange(mreal v1,mreal v2,bool add=false);
404 /// Set ranges for automatic variables
405 void SetAutoRanges(mreal x1, mreal x2, mreal y1=0, mreal y2=0, mreal z1=0, mreal z2=0, mreal c1=0, mreal c2=0);
406 /// Set axis origin
407 void SetOrigin(mreal x0, mreal y0, mreal z0=NAN, mreal c0=NAN);
408 /// Save ranges into internal variable and put parsed
409 mreal SaveState(const char *opt);
410 /// Load ranges from internal variable
411 void LoadState();
412 /// Increase ZMin
AdjustZMin()413 mreal AdjustZMin() { ZMin /= MGL_FEPSILON; return Max.z - ZMin*(Max.z-Min.z); }
414
415 /// Safetly set the transformation formulas for coordinate.
416 void SetFunc(const char *EqX, const char *EqY, const char *EqZ=0, const char *EqA=0);
417 /// Set one of predefined transformation rule
418 void SetCoor(int how);
419 /// Safetly set the cutting off condition (formula).
420 void CutOff(const char *EqCut);
421 /// Set to draw Ternary axis (triangle like axis, grid and so on)
422 void Ternary(int tern);
423
424 /// Set cutting for points outside of bounding box
SetCut(bool val)425 inline void SetCut(bool val) { set(val, MGL_ENABLE_CUT); }
426 /// Set additional cutting box
SetCutBox(mreal x1,mreal y1,mreal z1,mreal x2,mreal y2,mreal z2)427 inline void SetCutBox(mreal x1, mreal y1, mreal z1, mreal x2, mreal y2, mreal z2)
428 { CutMin.Set(x1,y1,z1); CutMax.Set(x2,y2,z2); }
SetCutBox(const mglPoint & v1,const mglPoint & v2)429 inline void SetCutBox(const mglPoint &v1, const mglPoint &v2) { CutMin=v1; CutMax=v2; }
430 /// Reset mask to solid state
ResetMask()431 inline void ResetMask() { mask = MGL_SOLID_MASK; MaskAn = DefMaskAn; }
432 /// Set default mask rotation angle
SetMaskAngle(int angle)433 inline void SetMaskAngle(int angle) { DefMaskAn = angle; }
434
435 /// Set the using of light on/off.
Light(bool enable)436 virtual bool Light(bool enable)
437 { bool t=get(MGL_ENABLE_LIGHT); set(enable,MGL_ENABLE_LIGHT); return t; }
438 /// Set to attach light sources to inplot.
AttachLight(bool enable)439 virtual bool AttachLight(bool enable)
440 { bool t=get(MGL_LOCAL_LIGHT); set(enable,MGL_LOCAL_LIGHT); return t; }
441 /// Set ambient light brightness
442 virtual void SetAmbient(mreal bright=0.5);
443 /// Set diffusive light brightness
444 virtual void SetDiffuse(mreal bright=0.5);
445 /// Use diffusive light (only for local light sources)
SetDifLight(bool dif)446 inline void SetDifLight(bool dif) { SetDiffuse(dif?0.5:0); }
447 /// Set the transparency on/off.
Alpha(bool enable)448 virtual bool Alpha(bool enable)
449 { bool t=get(MGL_ENABLE_ALPHA); set(enable,MGL_ENABLE_ALPHA); return t; }
450 /// Set default value of alpha-channel
SetAlphaDef(mreal val)451 inline void SetAlphaDef(mreal val) { AlphaDef=val; }
452 /// Set default palette
SetPalette(const char * colors)453 inline void SetPalette(const char *colors)
454 { Txt[0].Set(mgl_have_color(colors)?colors:MGL_DEF_PAL,-1); }
ResetPal()455 inline void ResetPal() { CurrPal=0; }
GetNumPal(long id)456 inline long GetNumPal(long id) const { return Txt[labs(id)/256].n; }
457 /// Set default color scheme
SetDefScheme(const char * colors)458 inline void SetDefScheme(const char *colors)
459 { Txt[1].Set(mgl_have_color(colors)?colors:MGL_DEF_SCH); }
460
461 /// Set number of mesh lines
SetMeshNum(int val)462 inline void SetMeshNum(int val) { MeshNum=val; }
463 /// Set relative width of rectangles in Bars, Barh, BoxPlot
SetBarWidth(mreal val)464 inline void SetBarWidth(mreal val) { BarWidth=val>0?val:-BarWidth*val; }
465 /// Set size of marks
SetMarkSize(mreal val)466 inline void SetMarkSize(mreal val) { MarkSize=val>0?0.02*val:-val*MarkSize; }
467 /// Set size of arrows
SetArrowSize(mreal val)468 inline void SetArrowSize(mreal val) { ArrowSize=val>0?0.03*val:-val*ArrowSize; }
469 /// Get unscaled arrow size
GetArrowSize()470 inline mreal GetArrowSize() const { return ArrowSize/0.03; }
471
472 /// Set warning code ant fill Message
473 void SetWarn(int code, const char *who);
GetWarn()474 int inline GetWarn() const { return WarnCode; }
475
476 virtual void StartAutoGroup (const char *)=0;
477 void StartGroup(const char *name, int id);
478 virtual void EndGroup()=0; // { LoadState(); }
479 /// Highlight group
Highlight(int id)480 inline void Highlight(int id) { HighId=id; }
481
482 /// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72)
483 virtual void SetFontSizePT(mreal pt, int dpi=72){ FontSize = pt*27.f/dpi; }
484 /// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt)
485 inline void SetFontSizeCM(mreal cm, int dpi=72) { SetFontSizePT(cm*28.45f,dpi); }
486 /// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt)
487 inline void SetFontSizeIN(mreal in, int dpi=72) { SetFontSizePT(in*72.27f,dpi); }
488 /// Set font typeface. Note that each mglFont instance can be used with ONLY ONE mglGraph instance at a moment of time!
489 void SetFont(mglFont *f);
490 /// Get current typeface. Note that this variable can be deleted at next SetFont() call!
GetFont()491 inline mglFont *GetFont() { return fnt; }
492 /// Restore font
493 void RestoreFont();
494 /// Load font from file
495 void LoadFont (const char *name, const char *path=NULL);
496 /// Copy font from another mglGraph instance
497 void CopyFont(mglBase *gr);
498 /// Set default font size
499 void SetFontHscale(mreal val);
SetFontSize(mreal val)500 inline void SetFontSize(mreal val) { FontSize=val>0 ? val:-FontSize*val; }
GetFontSize()501 inline mreal GetFontSize() const { return FontSize; }
502 mreal TextWidth(const char *text, const char *font, mreal size) const MGL_FUNC_PURE;
503 mreal TextWidth(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE;
504 mreal TextHeight(const char *text, const char *font, mreal size) const MGL_FUNC_PURE;
505 mreal TextHeight(const wchar_t *text, const char *font, mreal size) const MGL_FUNC_PURE;
506 mreal TextHeight(const char *font, mreal size) const MGL_FUNC_PURE;
FontFactor()507 inline mreal FontFactor() const { return font_factor; }
508 virtual mreal GetRatio() const MGL_FUNC_CONST;
509 virtual int GetWidth() const MGL_FUNC_CONST;
510 virtual int GetHeight() const MGL_FUNC_CONST;
511 /// Add user-defined glyph
512 void DefineGlyph(HCDT x, HCDT y, unsigned char id=0);
513
514 /// Set to use or not text rotation
SetRotatedText(bool val)515 inline void SetRotatedText(bool val) { set(val,MGL_ENABLE_RTEXT); }
516 /// Set default font style and color
SetFontDef(const char * font)517 inline void SetFontDef(const char *font){ mgl_strncpy(FontDef, font, 31); }
518 /// Set to use or not text rotation
SetTickRotate(bool val)519 inline void SetTickRotate(bool val) { set(val,MGL_TICKS_ROTATE); }
520 /// Set to use or not text rotation
SetTickSkip(bool val)521 inline void SetTickSkip(bool val) { set(val,MGL_TICKS_SKIP); }
522
523 /// Add string to legend
524 void AddLegend(const char *text,const char *style);
525 void AddLegend(const wchar_t *text,const char *style);
526 /// Clear saved legend string
ClearLegend()527 inline void ClearLegend() { Leg.clear(); }
528
529 /// Set plot quality
530 virtual void SetQuality(int qual=MGL_DRAW_NORM) { Quality=qual; }
GetQuality()531 inline int GetQuality() const { return Quality; }
532 inline void SetDrawReg(long nx=1, long ny=1, long m=0) { dr_x=nx; dr_y=ny; dr_p=m; }
533
534 // ~~~~~~~~~~~~~~~~~~~~~~ Developer functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
535 /// Add point to the Pnt and return its position
536 inline long AddPnt(const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
537 { return AddPnt(&B,p,c,n,a,scl); }
538 long AddPnt(const mglMatrix *M, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1);
539 bool AddPntQ(mglPnt &q, const mglMatrix *M, mglPoint p, mreal c=-1, mglPoint n=mglPoint(NAN), mreal a=-1, int scl=1);
540 inline bool AddPntQ(mglPnt &q, mglPoint p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
541 { return AddPntQ(q,&B,p,c,n,a,scl); }
542 inline bool AddPntQ(long id, const mglMatrix *M, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
543 { return AddPntQ(Pnt[id],M,p,c,n,a,scl); }
544 inline bool AddPntQ(long id, const mglPoint &p, mreal c=-1, const mglPoint &n=mglPoint(NAN), mreal a=-1, int scl=1)
545 { return AddPntQ(Pnt[id],&B,p,c,n,a,scl); }
SetPntOff(size_t id)546 inline void SetPntOff(size_t id) { Pnt[id].x=NAN; }
547 long AllocPnts(size_t num);
548 long PushPnts(size_t num, const mglPnt *qq);
549 long CopyNtoC(long k, mreal c);
550 bool CopyNtoC(mglPnt &q, long k, mreal c);
CopyNtoC(long id,long k,mreal c)551 inline bool CopyNtoC(long id, long k, mreal c)
552 { return (id>=0)?CopyNtoC(Pnt[id],k,c):false; }
553 long CopyProj(long from, const mglPoint &p, const mglPoint &n, short sub=0);
554 bool CopyProj(mglPnt &q, long from, const mglPoint &p, const mglPoint &n, short sub=0);
555 void CopyProj(long id, long from, const mglPoint &p, const mglPoint &n, short sub=0)
556 { if(id>=0) CopyProj(Pnt[id],from,p,n,sub); }
DisablePnt(long id)557 void DisablePnt(long id) { Pnt[id].x = NAN; }
SetRGBA(long k,const mglColor & c)558 void SetRGBA(long k, const mglColor &c)
559 { if(k>=0) {mglPnt &p=Pnt[k]; p.r = c.r; p.g = c.g; p.b = c.b; p.a = c.a;} }
560 virtual void Reserve(long n); ///< Allocate n-cells for Pnt and return current position
561 /// Set to reduce accuracy of points (to reduce size of output files)
SetReduceAcc(bool val)562 inline void SetReduceAcc(bool val) { set(val, MGL_REDUCEACC); }
563 /// Add glyph of current font to the Glf and return its position
564 long AddGlyph(int s, long j);
565 /// Add glyph to the Glf and return its position
566 long AddGlyph(unsigned char id);
567 /// Add active point as k-th element of Pnt
568 void AddActive(long k,int n=0);
569 /// Clear unused points and primitives
570 void ClearUnused();
571
GetPenWidth()572 inline mreal GetPenWidth() { return PenWidth; }
573
GetB()574 inline const mglMatrix *GetB() const { return &B; }
GetPntP(long i)575 inline mglPoint GetPntP(long i) const
576 { const mglPnt &p=Pnt[i]; return mglPoint(p.x,p.y,p.z); }
GetPntN(long i)577 inline mglPoint GetPntN(long i) const
578 { const mglPnt &p=Pnt[i]; return mglPoint(p.u,p.v,p.w); }
GetPntC(long i)579 inline mglColor GetPntC(long i) const
580 { const mglPnt &p=Pnt[i]; return mglColor(p.r,p.g,p.b,p.a); }
GetClrC(long i)581 inline float GetClrC(long i) const { return Pnt[i].c; }
GetGlf(long i)582 inline const mglGlyph &GetGlf(long i) const { return Glf[i]; }
GetGlfNum()583 inline long GetGlfNum() const { return Glf.size(); }
GetPnt(long i)584 inline const mglPnt &GetPnt(long i) const { return Pnt[i]; }
GetPntNum()585 inline long GetPntNum() const { return Pnt.size(); }
SamePnt(long i,long j)586 inline bool SamePnt(long i, long j) const
587 {
588 if(i<0 || j<0) return true;
589 const mglPnt &p=Pnt[i], &q=Pnt[j];
590 return mgl_isnan(p.x) || mgl_isnan(q.x) || (p.x==q.x && p.y==q.y);
591 }
ValidPnt(size_t i)592 inline bool ValidPnt(size_t i) { return mgl_isnum(Pnt[i].x); }
593 // inline mglPrim &GetPrm(long i) { return Prm[i]; }
594 inline mglPrim &GetPrm(long i, bool sort=true)
595 { return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i]; }
596 inline const mglPrim &GetPrm(long i, bool sort=true) const
597 { return (sort && PrmInd) ? Prm[PrmInd[i]]:Prm[i]; }
GetPrmNum()598 inline long GetPrmNum() const { return Prm.size(); }
GetPtx(long i)599 inline const mglText &GetPtx(long i) const { return Ptx[i]; }
GetPtxNum()600 inline long GetPtxNum() const { return Ptx.size(); }
GetTxt(long i)601 inline const mglTexture &GetTxt(long i) const { return Txt[i]; }
GetTxtNum()602 inline long GetTxtNum() const { return Txt.size(); }
603 /// Scale coordinates and cut off some points
604 virtual bool ScalePoint(const mglMatrix *M, mglPoint &p, mglPoint &n, bool use_nan=true) const;
605
GetSub(size_t i)606 inline const mglBlock &GetSub(size_t i) const { return Sub[i]; }
GetSub()607 inline const mglBlock &GetSub() const { return Sub.back(); }
608
609 virtual mreal GetOrgX(char dir, bool inv=false) const=0; ///< Get Org.x (parse NAN value)
610 virtual mreal GetOrgY(char dir, bool inv=false) const=0; ///< Get Org.y (parse NAN value)
611 virtual mreal GetOrgZ(char dir, bool inv=false) const=0; ///< Get Org.z (parse NAN value)
612
613 /// Get color depending on single variable z, which should be scaled if scale=true
614 inline mreal GetC(long s,mreal z,bool scale = true) const
615 { return s+(scale?GetA(z):(z<0?0:z/MGL_FEPSILON)); }
616 // { return s+(scale?GetA(z):(z>0?z/MGL_FEPSILON:0)); }
617 /// Get alpha value depending on single variable a
618 mreal GetA(mreal a) const MGL_FUNC_PURE;
619 /// Set pen/palette
620 char SetPenPal(const char *stl, long *id=0, bool pal=true);
621 /// Add texture (like color scheme) and return the position of first color
622 long AddTexture(const char *cols, int smooth=0);
623 // inline mreal AddTexture(char col) { return AddTexture(mglColor(col)); }
624 mreal AddTexture(mglColor col);
DefColor(mglColor col)625 inline void DefColor(mglColor col) { CDef = AddTexture(col); }
626 /// Set mask for face coloring
627 void SetMask(const char *mask);
628 /// Set next color from palette
629 mreal NextColor(long &id);
630 mreal NextColor(long id, long sh);
631
632 virtual void mark_plot(long p, char type, mreal size=1)=0;
633 virtual void arrow_plot(long p1, long p2, char st)=0;
634 virtual void line_plot(long p1, long p2)=0;
635 virtual void trig_plot(long p1, long p2, long p3)=0;
636 virtual void quad_plot(long p1, long p2, long p3, long p4)=0;
637 virtual void smbl_plot(long p1, char id, double size)=0;
638 void curve_plot(size_t n, size_t kq, size_t step=1);
639 virtual void Glyph(mreal x, mreal y, mreal f, int style, long icode, mreal col)=0;
640 virtual float GetGlyphPhi(const mglPnt &q, float phi)=0;
641 virtual mreal text_plot(long p,const wchar_t *text,const char *fnt,mreal size=-1,mreal sh=0,mreal col=-('k'),bool rot=true)=0;
642 void vect_plot(long p1, long p2, mreal s=1);
643
644 // check if visible
645 virtual bool trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const =0;
646 virtual bool quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const =0;
647
mark_size()648 inline mreal mark_size() { return MarkSize*font_factor; }
649 // inline char last_color() { return last_style[1]; }
last_line()650 inline const char *last_line() { return last_style; }
651 int PrmCmp(size_t i, size_t j) const MGL_FUNC_PURE; // compare 2 primitives with indexes i,j
652 /// Check if plot termination is asked
NeedStop()653 bool NeedStop() { if(event_cb) event_cb(event_par); return Stop; }
654 /// Ask to stop drawing
655 void AskStop(bool stop=true) { Stop = stop; }
656 /// Set callback function for event processing
SetEventFunc(void (* func)(void *),void * par)657 void SetEventFunc(void (*func)(void *), void *par) { event_cb=func; event_par=par; }
658
659 protected:
660 bool limit_pm1; ///< limit coordinates in range [-1,+1] for OpenGL only
661 volatile bool Stop; ///< Flag that execution should be terminated.
662 void (*event_cb)(void *); ///< Function to be called for event processing
663 void *event_par; ///< Parameter for event processing function
664
665 mglPoint OMin; ///< Lower edge for original axis (before scaling)
666 mglPoint OMax; ///< Upper edge for original axis (before scaling)
667 mglPoint AMin; ///< Lower edge for axis scaling
668 mglPoint AMax; ///< Upper edge for axis scaling
669 mglPoint FMin; ///< Actual lower edge after transformation formulas.
670 mglPoint FMax; ///< Actual upper edge after transformation formulas.
671 mglPoint Org; ///< Center of axis cross section.
672 int WarnCode; ///< Warning code
673 size_t *PrmInd; ///< Indexes of sorted primitives
674 mglStack<mglPnt> Pnt; ///< Internal points
675 mglStack<mglPrim> Prm; ///< Primitives (lines, triangles and so on) -- need for export
676 std::vector<mglBlock> Sub; ///< InPlot regions
677 std::vector<mglText> Ptx; ///< Text labels for mglPrim
678 std::vector<mglText> Leg; ///< Text labels for legend
679 std::vector<mglGlyph> Glf; ///< Glyphs data
680 std::vector<mglTexture> Txt; ///< Pointer to textures
681 #if MGL_HAVE_PTHREAD
682 pthread_mutex_t mutexPnt, mutexTxt, mutexLeg, mutexGlf, mutexAct, mutexDrw;
683 pthread_mutex_t mutexSub, mutexPrm, mutexPtx, mutexStk, mutexGrp, mutexClf;
684 #endif
685 void *lockClf; ///< pointer to mutex for mglStack
686
687 int TernAxis; ///< Flag that Ternary axis is used
688 unsigned PDef; ///< Pen bit mask
689 mreal pPos; ///< Current position in pen mask
690 mreal PenWidth; ///< Pen width for further line plotting (must be >0 !!!)
691 // long numT; ///< Number of textures
692 mreal AmbBr; ///< Default ambient light brightness
693 mreal DifBr; ///< Default diffusive light brightness
694
695 mreal persp; ///< Original value for perspective
696 mglMatrix Bp; ///< Transformation matrix for View() and Zoom()
697 mglMatrix B; ///< Transformation matrix
698 mglMatrix B1; ///< Transformation matrix for colorbar
699
700 mglFont *fnt; ///< Class for printing vector text
701 mreal FontSize; ///< The size of font for tick and axis labels
702 char FontDef[32]; ///< Font specification (see mglGraph::Puts). Default is Roman with align at center.
703 int Quality; ///< Quality of plot (0x0-pure, 0x1-fast; 0x2-fine; 0x4 - low memory)
704
705 HMEX fx; ///< Transformation formula for x direction.
706 HMEX fy; ///< Transformation formula for y direction.
707 HMEX fz; ///< Transformation formula for z direction.
708 HMEX fa; ///< Transformation formula for coloring.
709 HMEX fc; ///< Cutting off condition (formula).
710
711 long CurrPal; ///< Current palette index
712 mreal MarkSize; ///< The size of marks for 1D plots.
713 mreal ArrowSize; ///< The size of arrows.
714 char last_style[64];///< Last pen style TODO: replace by std::string
715 mreal font_factor; ///< Font scaling factor
716
717 long dr_x, dr_y, dr_p; ///< default drawing region for quality&4 mode
718
719 virtual void LightScale(const mglMatrix *M)=0; ///< Scale positions of light sources
720 void ClearPrmInd();
721
722 // block for SaveState()
723 mglPoint MinS; ///< Saved lower edge of bounding box for graphics.
724 mglPoint MaxS; ///< Saved upper edge of bounding box for graphics.
725 mreal MSS, ASS, FSS, ADS, MNS, LSS; ///< Saved state
726 mreal PrevState; ///< Previous value of SaveState()
727 long CSS; ///< Saved flags
728 bool saved; ///< State is saved
729 std::string leg_str;///< text to be save in legend
730
731 union
732 {
733 uint64_t mask; ///< Mask to be used for coloring
734 unsigned char mask_ch[8];
735 };
736 int MaskAn; ///< Mask rotation angle in degrees
737 int DefMaskAn; ///< Default mask rotation angle in degrees
738
739 private:
mglBase(const mglBase &)740 mglBase(const mglBase &){} // copying is not allowed
741 const mglBase &operator=(const mglBase &t){return t;} // copying is not allowed
742
743 mglPoint CutMin; ///< Lower edge of bounding box for cut off.
744 mglPoint CutMax; ///< Upper edge of bounding box for cut off.
745
746 bool RecalcCRange(); ///< Recalculate internal parameter for correct coloring.
747 void RecalcBorder(); ///< Recalculate internal parameter for correct transformation rules.
748 bool SetFBord(mreal x,mreal y,mreal z); ///< Set internal boundng box depending on transformation formula
749 void ClearEq(); ///< Clear the used variables for axis transformation
750 };
751 //-----------------------------------------------------------------------------
752 bool MGL_EXPORT mgl_check_dim0(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false);
753 bool MGL_EXPORT mgl_check_dim1(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *name, bool less=false);
754 bool MGL_EXPORT mgl_check_dim2(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, bool less=false);
755 bool MGL_EXPORT mgl_check_dim3(HMGL gr, bool both, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *name);
756 bool MGL_EXPORT mgl_check_vec3(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *name);
757 bool MGL_EXPORT mgl_check_trig(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *name, int d=3);
758 bool MGL_EXPORT mgl_isnboth(HCDT x, HCDT y, HCDT z, HCDT a);
759 bool MGL_EXPORT mgl_isboth(HCDT x, HCDT y, HCDT z, HCDT a);
mgl_islog(mreal a,mreal b)760 inline bool mgl_islog(mreal a,mreal b) { return a*b>0 && (b/a+a/b)>=10.1; }
761 //-----------------------------------------------------------------------------
762 #endif
763 #endif
764