1@c ------------------------------------------------------------------ 2@chapter Other classes 3@nav{} 4 5There are few end-user classes: @code{mglGraph} (see @ref{MathGL core}), @code{mglWindow} and @code{mglGLUT} (see @ref{Widget classes}), @code{mglData} (see @ref{Data processing}), @code{mglParse} (see @ref{MGL scripts}). Exactly these classes I recommend to use in most of user programs. All methods in all of these classes are inline and have exact C/Fortran analogue functions. This give compiler independent binary libraries for MathGL. 6 7However, sometimes you may need to extend MathGL by writing yours own plotting functions or handling yours own data structures. In these cases you may need to use low-level API. This chapter describes it. 8 9@fig{classes, Class diagram for MathGL} 10 11The internal structure of MathGL is rather complicated. There are C++ classes @code{mglBase}, @code{mglCanvas}, ... for drawing primitives and positioning the plot (blue ones in the figure). There is a layer of C functions, which include interface for most important methods of these classes. Also most of plotting functions are implemented as C functions. After it, there are ``inline'' front-end classes which are created for user convenience (yellow ones in the figure). Also there are widgets for FLTK, Qt and other libraries (green ones in the figure). 12 13Below I show how this internal classes can be used. 14 15@menu 16* mglBase class:: 17* mglDataA class:: 18* mglColor class:: 19* mglPoint class:: 20@end menu 21 22 23@c ------------------------------------------------------------------ 24@external{} 25@node mglBase class, mglDataA class, , Other classes 26@section Define new kind of plot (mglBase class) 27@nav{} 28 29Basically most of new kinds of plot can be created using just MathGL primitives (see @ref{Primitives}). However the usage of @code{mglBase} methods can give you higher speed of drawing and better control of plot settings. 30 31All plotting functions should use a pointer to @code{mglBase} class (or @code{HMGL} type in C functions) due to compatibility issues. Exactly such type of pointers are used in front-end classes (@code{mglGraph, mglWindow}) and in widgets (@code{QMathGL, Fl_MathGL}). 32 33MathGL tries to remember all vertexes and all primitives and plot creation stage, and to use them for making final picture by demand. Basically for making plot, you need to add vertexes by @code{AddPnt()} function, which return index for new vertex, and call one of primitive drawing function (like @code{mark_plot(), arrow_plot(), line_plot(), trig_plot(), quad_plot(), text_plot()}), using vertex indexes as argument(s). @code{AddPnt()} function use 2 mreal numbers for color specification. First one is positioning in textures -- integer part is texture index, fractional part is relative coordinate in the texture. Second number is like a transparency of plot (or second coordinate in the 2D texture). 34 35I don't want to put here detailed description of @code{mglBase} class. It was rather well documented in @code{mgl2/base.h} file. I just show and example of its usage on the base of circle drawing. 36 37First, we should prototype new function @code{circle()} as C function. 38@verbatim 39#ifdef __cplusplus 40extern "C" { 41#endif 42void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); 43#ifdef __cplusplus 44} 45#endif 46@end verbatim 47This is done for generating compiler independent binary. Because only C-functions have standard naming mechanism, the same for any compilers. 48 49Now, we create a C++ file and put the code of function. I'll write it line by line and try to comment all important points. 50@verbatim 51void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) 52{ 53@end verbatim 54First, we need to check all input arguments and send warnings if something is wrong. In our case it is negative value of @var{r} argument. We just send warning, since it is not critical situation -- other plot still can be drawn. 55@verbatim 56 if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } 57@end verbatim 58Next step is creating a group. Group keep some general setting for plot (like options) and useful for export in 3d files. 59@verbatim 60 static int cgid=1; gr->StartGroup("Circle",cgid++); 61@end verbatim 62Now let apply options. Options are rather useful things, generally, which allow one easily redefine axis range(s), transparency and other settings (see @ref{Command options}). 63@verbatim 64 gr->SaveState(opt); 65@end verbatim 66I use global setting for determining the number of points in circle approximation. Note, that user can change @code{MeshNum} by options easily. 67@verbatim 68 const int n = gr->MeshNum>1?gr->MeshNum : 41; 69@end verbatim 70Let try to determine plot specific flags. MathGL functions expect that most of flags will be sent in string. In our case it is symbol @samp{@@} which set to draw filled circle instead of border only (last will be default). Note, you have to handle @code{NULL} as string pointer. 71@verbatim 72 bool fill = mglchr(stl,'@'); 73@end verbatim 74Now, time for coloring. I use palette mechanism because circle have few colors: one for filling and another for border. @code{SetPenPal()} function parse input string and write resulting texture index in @var{pal}. Function return the character for marker, which can be specified in string @var{str}. Marker will be plotted at the center of circle. I'll show on next sample how you can use color schemes (smooth colors) too. 75@verbatim 76 long pal=0; 77 char mk=gr->SetPenPal(stl,&pal); 78@end verbatim 79Next step, is determining colors for filling and for border. First one for filling. 80@verbatim 81 mreal c=gr->NextColor(pal), d; 82@end verbatim 83Second one for border. I use black color (call @code{gr->AddTexture('k')}) if second color is not specified. 84@verbatim 85 mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); 86@end verbatim 87If user want draw only border (@code{fill=false}) then I use first color for border. 88@verbatim 89 if(!fill) k=c; 90@end verbatim 91Now we should reserve space for vertexes. This functions need @code{n} for border, @code{n+1} for filling and @code{1} for marker. So, maximal number of vertexes is @code{2*n+2}. Note, that such reservation is not required for normal work but can sufficiently speed up the plotting. 92@verbatim 93 gr->Reserve(2*n+2); 94@end verbatim 95We've done with setup and ready to start drawing. First, we need to add vertex(es). Let define NAN as normals, since I don't want handle lighting for this plot, 96@verbatim 97 mglPoint q(NAN,NAN); 98@end verbatim 99and start adding vertexes. First one for central point of filling. I use @code{-1} if I don't need this point. The arguments of @code{AddPnt()} function is: @code{mglPoint(x,y,z)} -- coordinate of vertex, @code{c} -- vertex color, @code{q} -- normal at vertex, @code{-1} -- vertex transparency (@code{-1} for default), @code{3} bitwise flag which show that coordinates will be scaled (@code{0x1}) and will not be cutted (@code{0x2}). 100@verbatim 101 long n0,n1,n2,m1,m2,i; 102 n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; 103@end verbatim 104Similar for marker, but we use different color @var{k}. 105@verbatim 106 n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; 107@end verbatim 108Draw marker. 109@verbatim 110 if(mk) gr->mark_plot(n2,mk); 111@end verbatim 112Time for drawing circle itself. I use @code{-1} for @var{m1}, @var{n1} as sign that primitives shouldn't be drawn for first point @code{i=0}. 113@verbatim 114 for(i=0,m1=n1=-1;i<n;i++) 115 { 116@end verbatim 117Each function should check @code{Stop} variable and return if it is non-zero. It is done for interrupting drawing for system which don't support multi-threading. 118@verbatim 119 if(gr->Stop) return; 120@end verbatim 121Let find coordinates of vertex. 122@verbatim 123 mreal t = i*2*M_PI/(n-1.); 124 mglPoint p(x+r*cos(t), y+r*sin(t), z); 125@end verbatim 126Save previous vertex and add next one 127@verbatim 128 n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); 129@end verbatim 130and copy it for border but with different color. Such copying is much faster than adding new vertex using @code{AddPnt()}. 131@verbatim 132 m2 = m1; m1 = gr->CopyNtoC(n1,k); 133@end verbatim 134Now draw triangle for filling internal part 135@verbatim 136 if(fill) gr->trig_plot(n0,n1,n2); 137@end verbatim 138and draw line for border. 139@verbatim 140 gr->line_plot(m1,m2); 141 } 142@end verbatim 143Drawing is done. Let close group and return. 144@verbatim 145 gr->EndGroup(); 146} 147@end verbatim 148 149Another sample I want to show is exactly the same function but with smooth coloring using color scheme. So, I'll add comments only in the place of difference. 150 151@verbatim 152void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) 153{ 154@end verbatim 155In this case let allow negative radius too. Formally it is not the problem for plotting (formulas the same) and this allow us to handle all color range. 156@verbatim 157//if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } 158 159 static int cgid=1; gr->StartGroup("CircleCS",cgid++); 160 gr->SaveState(opt); 161 const int n = gr->MeshNum>1?gr->MeshNum : 41; 162 bool fill = mglchr(stl,'@'); 163@end verbatim 164Here is main difference. We need to create texture for color scheme specified by user 165@verbatim 166 long ss = gr->AddTexture(stl); 167@end verbatim 168But we need also get marker and color for it (if filling is enabled). Let suppose that marker and color is specified after @samp{:}. This is standard delimiter which stop color scheme entering. So, just lets find it and use for setting pen. 169@verbatim 170 const char *pen=0; 171 if(stl) pen = strchr(stl,':'); 172 if(pen) pen++; 173@end verbatim 174The substring is placed in @var{pen} and it will be used as line style. 175@verbatim 176 long pal=0; 177 char mk=gr->SetPenPal(pen,&pal); 178@end verbatim 179Next step, is determining colors for filling and for border. First one for filling. 180@verbatim 181 mreal c=gr->GetC(ss,r); 182@end verbatim 183Second one for border. 184@verbatim 185 mreal k=gr->NextColor(pal); 186@end verbatim 187The rest part is the same as in previous function. 188@verbatim 189 if(!fill) k=c; 190 191 gr->Reserve(2*n+2); 192 mglPoint q(NAN,NAN); 193 long n0,n1,n2,m1,m2,i; 194 n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; 195 n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; 196 if(mk) gr->mark_plot(n2,mk); 197 for(i=0,m1=n1=-1;i<n;i++) 198 { 199 if(gr->Stop) return; 200 mreal t = i*2*M_PI/(n-1.); 201 mglPoint p(x+r*cos(t), y+r*sin(t), z); 202 n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); 203 m2 = m1; m1 = gr->CopyNtoC(n1,k); 204 if(fill) gr->trig_plot(n0,n1,n2); 205 gr->line_plot(m1,m2); 206 } 207 gr->EndGroup(); 208} 209@end verbatim 210 211The last thing which we can do is derive our own class with new plotting functions. Good idea is to derive it from @code{mglGraph} (if you don't need extended window), or from @code{mglWindow} (if you need to extend window). So, in our case it will be 212@verbatim 213class MyGraph : public mglGraph 214{ 215public: 216 inline void Circle(mglPoint p, mreal r, const char *stl="", const char *opt="") 217 { circle(p.x,p.y,p.z, r, stl, opt); } 218 inline void CircleCS(mglPoint p, mreal r, const char *stl="", const char *opt="") 219 { circle_cs(p.x,p.y,p.z, r, stl, opt); } 220}; 221@end verbatim 222Note, that I use @code{inline} modifier for using the same binary code with different compilers. 223 224So, the complete sample will be 225@verbatim 226#include <mgl2/mgl.h> 227//--------------------------------------------------------- 228#ifdef __cplusplus 229extern "C" { 230#endif 231void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); 232void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt); 233#ifdef __cplusplus 234} 235#endif 236//--------------------------------------------------------- 237class MyGraph : public mglGraph 238{ 239public: 240 inline void CircleCF(mglPoint p, mreal r, const char *stl="", const char *opt="") 241 { circle(p.x,p.y,p.z, r, stl, opt); } 242 inline void CircleCS(mglPoint p, mreal r, const char *stl="", const char *opt="") 243 { circle_cs(p.x,p.y,p.z, r, stl, opt); } 244}; 245//--------------------------------------------------------- 246void circle(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) 247{ 248 if(r<=0) { gr->SetWarn(mglWarnNeg,"Circle"); return; } 249 static int cgid=1; gr->StartGroup("Circle",cgid++); 250 gr->SaveState(opt); 251 const int n = gr->MeshNum>1?gr->MeshNum : 41; 252 bool fill = mglchr(stl,'@'); 253 long pal=0; 254 char mk=gr->SetPenPal(stl,&pal); 255 mreal c=gr->NextColor(pal), d; 256 mreal k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k'); 257 if(!fill) k=c; 258 gr->Reserve(2*n+2); 259 mglPoint q(NAN,NAN); 260 long n0,n1,n2,m1,m2,i; 261 n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; 262 n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; 263 if(mk) gr->mark_plot(n2,mk); 264 for(i=0,m1=n1=-1;i<n;i++) 265 { 266 if(gr->Stop) return; 267 mreal t = i*2*M_PI/(n-1.); 268 mglPoint p(x+r*cos(t), y+r*sin(t), z); 269 n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); 270 m2 = m1; m1 = gr->CopyNtoC(n1,k); 271 if(fill) gr->trig_plot(n0,n1,n2); 272 gr->line_plot(m1,m2); 273 } 274 gr->EndGroup(); 275} 276//--------------------------------------------------------- 277void circle_cs(HMGL gr, mreal x, mreal y, mreal z, mreal r, const char *stl, const char *opt) 278{ 279 static int cgid=1; gr->StartGroup("CircleCS",cgid++); 280 gr->SaveState(opt); 281 const int n = gr->MeshNum>1?gr->MeshNum : 41; 282 bool fill = mglchr(stl,'@'); 283 long ss = gr->AddTexture(stl); 284 const char *pen=0; 285 if(stl) pen = strchr(stl,':'); 286 if(pen) pen++; 287 long pal=0; 288 char mk=gr->SetPenPal(pen,&pal); 289 mreal c=gr->GetC(ss,r); 290 mreal k=gr->NextColor(pal); 291 if(!fill) k=c; 292 293 gr->Reserve(2*n+2); 294 mglPoint q(NAN,NAN); 295 long n0,n1,n2,m1,m2,i; 296 n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1; 297 n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1; 298 if(mk) gr->mark_plot(n2,mk); 299 for(i=0,m1=n1=-1;i<n;i++) 300 { 301 if(gr->Stop) return; 302 mreal t = i*2*M_PI/(n-1.); 303 mglPoint p(x+r*cos(t), y+r*sin(t), z); 304 n2 = n1; n1 = gr->AddPnt(p,c,q,-1,3); 305 m2 = m1; m1 = gr->CopyNtoC(n1,k); 306 if(fill) gr->trig_plot(n0,n1,n2); 307 gr->line_plot(m1,m2); 308 } 309 gr->EndGroup(); 310} 311//--------------------------------------------------------- 312int main() 313{ 314 MyGraph gr; 315 gr.Box(); 316 // first let draw circles with fixed colors 317 for(int i=0;i<10;i++) 318 gr.CircleCF(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), mgl_rnd()); 319 // now let draw circles with color scheme 320 for(int i=0;i<10;i++) 321 gr.CircleCS(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), 2*mgl_rnd()-1); 322} 323@end verbatim 324 325 326 327 328@c ------------------------------------------------------------------ 329@external{} 330@node mglDataA class, mglColor class, mglBase class, Other classes 331@section User defined types (mglDataA class) 332@nav{} 333 334@code{mglData} class have abstract predecessor class @code{mglDataA}. Exactly the pointers to @code{mglDataA} instances are used in all plotting functions and some of data processing functions. This was done for taking possibility to define yours own class, which will handle yours own data (for example, complex numbers, or differently organized data). And this new class will be almost the same as @code{mglData} for plotting purposes. 335 336However, the most of data processing functions will be slower as if you used @code{mglData} instance. This is more or less understandable -- I don't know how data in yours particular class will be organized, and couldn't optimize the these functions generally. 337 338There are few virtual functions which must be provided in derived classes. This functions give: 339@itemize @bullet 340@item 341the sizes of the data (@code{GetNx}, @code{GetNy}, @code{GetNz}), 342@item 343give data value and numerical derivatives for selected cell (@code{v}, @code{dvx}, @code{dvy}, @code{dvz}), 344@item 345give maximal and minimal values (@code{Maximal}, @code{Minimal}) -- you can use provided functions (like @code{mgl_data_max} and @code{mgl_data_min}), but yours own realization can be more efficient, 346@item 347give access to all element as in single array (@code{vthr}) -- you need this only if you want using MathGL's data processing functions. 348@end itemize 349 350Let me, for example define class @code{mglComplex} which will handle complex number and draw its amplitude or phase, depending on flag @var{use_abs}: 351@verbatim 352#include <complex> 353#include <mgl2/mgl.h> 354#define dual std::complex<double> 355class mglComplex : public mglDataA 356{ 357public: 358 long nx; ///< number of points in 1st dimensions ('x' dimension) 359 long ny; ///< number of points in 2nd dimensions ('y' dimension) 360 long nz; ///< number of points in 3d dimensions ('z' dimension) 361 dual *a; ///< data array 362 bool use_abs; ///< flag to use abs() or arg() 363 364 inline mglComplex(long xx=1,long yy=1,long zz=1) 365 { a=0; use_abs=true; Create(xx,yy,zz); } 366 virtual ~mglComplex() { if(a) delete []a; } 367 368 /// Get sizes 369 inline long GetNx() const { return nx; } 370 inline long GetNy() const { return ny; } 371 inline long GetNz() const { return nz; } 372 /// Create or recreate the array with specified size and fill it by zero 373 inline void Create(long mx,long my=1,long mz=1) 374 { nx=mx; ny=my; nz=mz; if(a) delete []a; 375 a = new dual[nx*ny*nz]; } 376 /// Get maximal value of the data 377 inline mreal Maximal() const { return mgl_data_max(this); } 378 /// Get minimal value of the data 379 inline mreal Minimal() const { return mgl_data_min(this); } 380 381protected: 382 inline mreal v(long i,long j=0,long k=0) const 383 { return use_abs ? abs(a[i+nx*(j+ny*k)]) : arg(a[i+nx*(j+ny*k)]); } 384 inline mreal vthr(long i) const 385 { return use_abs ? abs(a[i]) : arg(a[i]); } 386 inline mreal dvx(long i,long j=0,long k=0) const 387 { long i0=i+nx*(j+ny*k); 388 std::complex<double> res=i>0? (i<nx-1? (a[i0+1]-a[i0-1])/2.:a[i0]-a[i0-1]) : a[i0+1]-a[i0]; 389 return use_abs? abs(res) : arg(res); } 390 inline mreal dvy(long i,long j=0,long k=0) const 391 { long i0=i+nx*(j+ny*k); 392 std::complex<double> res=j>0? (j<ny-1? (a[i0+nx]-a[i0-nx])/2.:a[i0]-a[i0-nx]) : a[i0+nx]-a[i0]; 393 return use_abs? abs(res) : arg(res); } 394 inline mreal dvz(long i,long j=0,long k=0) const 395 { long i0=i+nx*(j+ny*k), n=nx*ny; 396 std::complex<double> res=k>0? (k<nz-1? (a[i0+n]-a[i0-n])/2.:a[i0]-a[i0-n]) : a[i0+n]-a[i0]; 397 return use_abs? abs(res) : arg(res); } 398}; 399int main() 400{ 401 mglComplex dat(20); 402 for(long i=0;i<20;i++) 403 dat.a[i] = 3*exp(-0.05*(i-10)*(i-10))*dual(cos(M_PI*i*0.3), sin(M_PI*i*0.3)); 404 mglGraph gr; 405 gr.SetRange('y', -M_PI, M_PI); gr.Box(); 406 407 gr.Plot(dat,"r","legend 'abs'"); 408 dat.use_abs=false; 409 gr.Plot(dat,"b","legend 'arg'"); 410 gr.Legend(); 411 gr.WritePNG("complex.png"); 412 return 0; 413} 414@end verbatim 415 416 417@c ------------------------------------------------------------------ 418@external{} 419@node mglColor class, mglPoint class, mglDataA class, Other classes 420@section mglColor class 421@nav{} 422@cindex mglColor 423 424Structure for working with colors. This structure is defined in @code{#include <mgl2/type.h>}. 425 426There are two ways to set the color in MathGL. First one is using of mreal values of red, green and blue channels for precise color definition. The second way is the using of character id. There are a set of characters specifying frequently used colors. Normally capital letter gives more dark color than lowercase one. @xref{Line styles}. 427 428@deftypecv {Parameter} mglColor @code{mreal} {r, g, b, a} 429Reg, green and blue component of color. 430@end deftypecv 431 432@deftypemethod mglColor @code{} mglColor (@code{mreal} R, @code{mreal} G, @code{mreal} B, @code{mreal} A=@code{1}) 433Constructor sets the color by mreal values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. 434@end deftypemethod 435@deftypemethod mglColor @code{} mglColor (@code{char} c=@code{'k'}, @code{mreal} bright=@code{1}) 436Constructor sets the color from character id. The black color is used by default. Parameter @var{br} set additional ``lightness'' of color. 437@end deftypemethod 438@deftypemethod mglColor @code{void} Set (@code{mreal} R, @code{mreal} G, @code{mreal} B, @code{mreal} A=@code{1}) 439Sets color from values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. 440@end deftypemethod 441@deftypemethod mglColor @code{void} Set (@code{mglColor} c, @code{mreal} bright=@code{1}) 442Sets color as ``lighted'' version of color @var{c}. 443@end deftypemethod 444@deftypemethod mglColor @code{void} Set (@code{char} p, @code{mreal} bright=@code{1}) 445Sets color from symbolic id. 446@end deftypemethod 447@deftypemethod mglColor @code{bool} Valid () 448Checks correctness of the color. 449@end deftypemethod 450@deftypemethod mglColor @code{mreal} Norm () 451Gets maximal of spectral component. 452@end deftypemethod 453@deftypemethod mglColor @code{bool} operator== (@code{const mglColor &}c) 454@deftypemethodx mglColor @code{bool} operator!= (@code{const mglColor &}c) 455Compare with another color 456@end deftypemethod 457 458@deftypemethod mglColor @code{bool} operator*= (@code{mreal} v) 459Multiplies color components by number @var{v}. 460@end deftypemethod 461 462@deftypemethod mglColor @code{bool} operator+= (@code{const mglColor &}c) 463Adds color @var{c} component by component. 464@end deftypemethod 465 466@deftypemethod mglColor @code{bool} operator-= (@code{const mglColor &}c) 467Subtracts color @var{c} component by component. 468@end deftypemethod 469 470 471@deftypefn {Library Function} {mglColor} operator+ (@code{const mglColor &}a, @code{const mglColor &}b) 472Adds colors by its RGB values. 473@end deftypefn 474@deftypefn {Library Function} @code{mglColor} operator- (@code{const mglColor &}a, @code{const mglColor &}b) 475Subtracts colors by its RGB values. 476@end deftypefn 477@deftypefn {Library Function} @code{mglColor} operator* (@code{const mglColor &}a, @code{mreal} b) 478@deftypefnx {Library Function} @code{mglColor} operator* (@code{mreal} a, @code{const mglColor &}b) 479Multiplies color by number. 480@end deftypefn 481@deftypefn {Library Function} @code{mglColor} operator/ (@code{const mglColor &}a, @code{mreal} b) 482Divide color by number. 483@end deftypefn 484@deftypefn {Library Function} @code{mglColor} operator! (@code{const mglColor &}a) 485Return inverted color. 486@end deftypefn 487 488@c ------------------------------------------------------------------ 489@external{} 490@node mglPoint class, , mglColor class, Other classes 491@section mglPoint class 492@nav{} 493@cindex mglPoint 494 495Structure describes point in space. This structure is defined in @code{#include <mgl2/type.h>} 496 497@deftypecv {Parameter} mglPoint @code{mreal} {x, y, z, c} 498Point coordinates @{x,y,z@} and one extra value @var{c} used for amplitude, transparency and so on. By default all values are zero. 499@end deftypecv 500 501@deftypemethod mglPoint @code{} mglPoint (@code{mreal} X=@code{0}, @code{mreal} Y=@code{0}, @code{mreal} Z=@code{0}, @code{mreal} C=@code{0}) 502Constructor sets the color by mreal values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1]. 503@end deftypemethod 504 505@deftypemethod mglPoint @code{bool} IsNAN () 506Returns @code{true} if point contain NAN values. 507@end deftypemethod 508@deftypemethod mglPoint @code{mreal} norm () 509Returns the norm @math{\sqrt@{x^2+y^2+z^2@}} of vector. 510@end deftypemethod 511@deftypemethod mglPoint @code{void} Normalize () 512Normalizes vector to be unit vector. 513@end deftypemethod 514@deftypemethod mglPoint @code{mreal} val (@code{int} i) 515Returns point component: @var{x} for @var{i}=0, @var{y} for @var{i}=1, @var{z} for @var{i}=2, @var{c} for @var{i}=3. 516@end deftypemethod 517 518 519@deftypefn {Library Function} @code{mglPoint} operator+ (@code{const mglPoint &}a, @code{const mglPoint &}b) 520Point of summation (summation of vectors). 521@end deftypefn 522@deftypefn {Library Function} @code{mglPoint} operator- (@code{const mglPoint &}a, @code{const mglPoint &}b) 523Point of difference (difference of vectors). 524@end deftypefn 525@deftypefn {Library Function} @code{mglPoint} operator* (@code{mreal} a, @code{const mglPoint &}b) 526@deftypefnx {Library Function} @code{mglPoint} operator* (@code{const mglPoint &}a, @code{mreal} b) 527Multiplies (scale) points by number. 528@end deftypefn 529@deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{mreal} b) 530Multiplies (scale) points by number 1/b. 531@end deftypefn 532@deftypefn {Library Function} @code{mreal} operator* (@code{const mglPoint &}a, @code{const mglPoint &}b) 533Scalar product of vectors. 534@end deftypefn 535 536@deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{const mglPoint &}b) 537Return vector of element-by-element product. 538@end deftypefn 539 540@deftypefn {Library Function} @code{mglPoint} operator^ (@code{const mglPoint &}a, @code{const mglPoint &}b) 541Cross-product of vectors. 542@end deftypefn 543@deftypefn {Library Function} @code{mglPoint} operator& (@code{const mglPoint &}a, @code{const mglPoint &}b) 544The part of @var{a} which is perpendicular to vector @var{b}. 545@end deftypefn 546@deftypefn {Library Function} @code{mglPoint} operator| (@code{const mglPoint &}a, @code{const mglPoint &}b) 547The part of @var{a} which is parallel to vector @var{b}. 548@end deftypefn 549 550@deftypefn {Library Function} @code{mglPoint} operator! (@code{const mglPoint &}a) 551Return vector perpendicular to vector @var{a}. 552@end deftypefn 553@deftypefn {Library Function} @code{mreal} mgl_norm (@code{const mglPoint &}a) 554Return the norm sqrt(|@var{a}|^2) of vector @var{a}. 555@end deftypefn 556 557@deftypefn {Library Function} @code{bool} operator== (@code{const mglPoint &}a, @code{const mglPoint &}b) 558Return true if points are the same. 559@end deftypefn 560@deftypefn {Library Function} @code{bool} operator!= (@code{const mglPoint &}a, @code{const mglPoint &}b) 561Return true if points are different. 562@end deftypefn 563 564@external{} 565 566