MathMod: An Interactive Plotting Program

## Table of contents:

- About MathMod
  1. Introduction
  2. Copyright
  3. Download
  4. Compile MathMod from source
  5. Documentation
  6. Release Notes
  7. Seeking-assistance
  8. Videos tutorials
- Introduction to Parametric/Implicit Equations
  1. Parametric equation
  2. Parametric surface
  3. Implicit function
  4. Implicit surface
  5. Functions of a Complex Variable
  6. Visualizing Functions of a Complex Variable
- Procedural texture
  1. Solid texturing
  2. Cellular texturing
- MathMod scripts
  1. Scripts file format
  2. Supported mathematical objects
  3. Mandatory Keys
  4. Optional Keys
  5. Texture and Pigment
     1. Texture object
     2. Pigment object
     3. Scripts Examples
  6. Internal Functions
  7. Internal parameters
  8. User defined variables
  9. Supported operators and mathematical functions
- Configuration file
- Animation and Morph effect
  1. Morph effect
  2. Rotation
  3. Making animated GIF or videos
- MathMod's GUI Reference
  1. Menu Items
     1. The Project Menu
     2. The Options Menu
     3. The Export Menu
     4. The Help Menu
  2. Tabbed pages
     1. The "Model Details" page
     2. The "Script Edit" page
     3. The "View Controls" page
     4. The "Appearance" page
     5. The "Sliders" page
- Scripts examples
  1. Models_Intersection
  2. CellNoiseSchwarz
  3. The_Dome_v1
  4. Pariso_02
  5. Arena_02

## About MathMod

1. ### Introduction

   MathMod is a portable interactive plotting and graphing program for Windows, Linux, MacOSX and many other platforms.
   MathMod allows to plot 3D mathematical surfaces, described by implicit or parametric equations, and offers a very large database of model samples that can be generated with it. It's Free and Open Source under the terms of the GPL licence version 2 or later.
   Apart from visualizing the actual shape, you are also free to edit the scripts and equations in order to understand how each parameter influences and reshapes the model.
   Moreover, it allows to export it's mathematical models to OBJ format and generate animations that showcase how the model morphs as it is given new parameters to work with.

2. ### Copyright

       Copyright (C) 2021 by Abderrahman Taha

       This program is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published by
       the Free Software Foundation; either version 2 of the License, or
       (at your option) any later version.

       This program is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       GNU General Public License for more details.

       You should have received a copy of the GNU General Public License
       along with this program; if not, write to the
       Free Software Foundation, Inc.,
       51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

3. ### Download

   Current MathMod version is 11.1
   Primary download sites on SourceForge and GitHub:
   1. GitHub
   2. SourceForge
   Video to show MathMod ability to animate a combination of parametric and iso surfaces

4. ### Compile MathMod from source

   1. Download Qt
   2. Download MathMod's source code
   3. In a command line window, execute: "qmake; make" OR use the qt-creator IDE to compile MathMod.pro project

5. ### Release Notes

   MathMod Version 11.1 Release Notes This release contains :
   1. Support of graphing functions with complex numbers Z=u+iv in 3D and 4D spaces (demo scripts: "Complex3D_xx" and "Complex4D_Saddle")
   2. Added support for HSV (hue, saturation, lightness) coloring model (script: "Complex_Domain_Coloring")
   3. Texture definitions (RGB and HSV) for parametric surfaces can now be expressed as functions of complex numbers
   4. Added a software implementation for the OpenGL variable gl_FrontFacing (fixed an issue with GPU drivers on MacOSX Catalina). The activation of this support is available from either:
   1. The Configuration file mathmodconfig.js: "OpenGlConfig"-->"GL_FrontFacingSupport"
   or
   2. GUI: "Appearance"-->"OpenGL Front Surface Support"
   5. Bug-fixes, code optimization and documentation update.
   6. For a complete list of changes made during the course of development, please visit: MathMod-11.1
   Release Notes date: 15/06/2021

6. ### Seeking-assistance

   Author: Abderrahman Taha (taha_ab@yahoo.fr)

   GitHub: https://github.com/parisolab/mathmod

   Home: https://sourceforge.net/projects/mathmod

   FaceBook: https://www.facebook.com/parisolab/

   Twitter :https://twitter.com/parisolab

7. ### Videos tutorials

   There are 15 videos tutorials on Youtube
   1. Tutorial 15: How to compile MathMod from source
   2. Tutorial 14: How to save temporary new scripts without editing MathMod's collection file
   3. Tutorial 13: How to create animated GIF images with MathMod and Gimp
   4. Tutorial 12 : How to use MathMod texture and pigmentation provided collections
   5. Tutorial 11 : How to edit a script with more than one component
   6. Tutorial 09: Steps to build the "Gyroid Ball" script animation
   7. Tutorial 08 : Video to show how to run the Gyroid Ball script animation
   8. Tutorial 06: How to modify colors and textures
   9. Tutorial 05: How to select/Deselect part of the surface by using the CND equation
   10. Tutorial 04 : How to configure MathMod's Look & Feel
   11. Tutorial 02: How to create/update a collection file for MathMod
   12. Tutorial 01: How to load a collection file in MathMod

## Introduction to parametric and implicit Equations

1. ### Parametric equation

   In mathematics, a parametric equation defines a group of quantities as functions of one or more independent variables called parameters.
   Parametric equations are commonly used to express the coordinates of the points that make up a geometric object such as a curve or surface, in which case the equations are collectively called a parametric representation or parameterization (alternatively spelled as parametrisation) of the object.
   For example, the equations : x = cos(t) y = sin(t)
   form a parametric representation of the unit circle, where t is the parameter: A point (x, y) is on the unit circle if and only if there is a value of t such that these two equations generate that point.
   In addition to curves and surfaces, parametric equations can describe manifolds and algebraic varieties of higher dimension, with the number of parameters being equal to the dimension of the manifold or variety, and the number of equations being equal to the dimension of the space in which the manifold or variety is considered.

2. ### Parametric surface

   A parametric surface is the image of an open subset of the Euclidean plane (typically R^2) by a continuous function, in a topological space, generally a Euclidean space of dimension at least three. Usually the function is supposed to be continuously differentiable.

3. ### Implicit function

   In mathematics, an implicit equation is a relation of the form R ( x 1 , … , x n ) = 0 , where R is a function of several variables (often a polynomial).
   For example, the implicit equation of the unit circle is x 2 + y 2 − 1 = 0 .

4. ### Implicit surface

   An implicit surface in a Euclidean space (or, more generally, in an affine space) of dimension 3 is the set of the common zeros of a differentiable function of three variables
   `f ( x , y , z ) = 0`

5. ### Functions of a Complex Variable

   In mathematics, a complex number is a number that can be expressed in the form a + bi, where a and b are real numbers, and i is a symbol called the imaginary unit, and satisfying the equation i^2 = −1.
   A complex function F = U+iV of a complex variable z=u+iv is introduced as a complex-valued function of two real variables, u and v : F(z) = F(u+iv) = U(u, v) +iV(u, v).
   Hence, to specify a complex function it is enough to specify two real functions: U(u, v) and V(u, v).
   `To give a simple example of this, consider f(z) = z^2 ==> f(u+iv) = u^2 - v^2 +i2*u*v`

6. ### Visualizing Functions of a Complex Variable

   A function of a complex variable, w = f(z), can be thought in terms of its real components: f(u+iv) = U(u,v) + iV(u,v).
   MathMod supported ways to visualize the set of points (u, v, U, V) satisfying this equation:
   - Explicitly dropping one of the coordinates allows us to render a 3D surface. We can also encode the remaining coordinate by coloring the surface(not yet supported)
     Script sample
     - (u, v, U) can be seen by graphing Re(f(u+iv))
     - (u, v, V) can be seen by graphing Im(f(u+iv))
     - (u, U, V) can be seen by graphing the real part of the inverse of f.
     - (v, U, V) can be seen by graphing the imaginary part of the inverse of f.
     - We can also graph the magnitude or phase of f(u+iv).
   - The points (u, v, U, V) represent a surface in four dimensions.
     This surface can be drawn using perspective projection in much the same way 3D surfaces are rendered on screen.
     Script sample

## Procedural texture

In computer graphics, a procedural texture is a texture created using a mathematical description (i.e. an algorithm) rather than directly stored data.
The advantage of this approach is low storage cost, unlimited texture resolution and easy texture mapping.
These kinds of textures are often used to model surface or volumetric representations of natural elements such as wood, marble, granite, metal, stone, and others.

1. ### Solid texturing

   Solid texturing is a process where the texture generating function is evaluated over R^3 at each visible surface point of the model so the resulting material properties (like color, shininess or normal) depends only on their 3D position, not their parametrized 2D surface position like in traditional 2D texture mapping.
   Consequently, solid textures are unaffected by distortions of the surface parameter space, such as you might see near the poles of a sphere.
   Initially these functions were based on simple combination of procedural noise functions like Simplex noise or Perlin noise.

2. ### Cellular texturing

   Cellular texturing differs from the majority of other procedural texture generating techniques as it does not depend on noise functions as its basis, although it is often used to complement the technique.
   Cellular textures are based on feature points which are scattered over a three-dimensional space.
   These points are then used to split up the space into small, randomly tiled regions called cells.
   These cells often look like "lizard scales", "pebbles", or "flagstones". Even though these regions are discrete, the cellular basis function itself is continuous and can be evaluated anywhere in space. Worley noise is a common type of cellular texture

## MathMod scripts

1. ### Scripts file format

   MathMod scripts are in JSON file format. A JSON file is a file that stores simple data structures and objects in JavaScript Object Notation (JSON) format, which is a standard data interchange format. It is primarily used for transmitting data between a web application and a server.
   JSON objects are written in key/value pairs. Keys must be strings, and values must be a valid JSON data type (string, number, object, array, boolean or null). Keys and values are separated by a colon. Each key/value pair is separated by a comma.

2. ### Supported mathematical objects:

   There are six major type of mathematical objects supported by MathMod:
   1. "Iso3D" : Isosurfaces
   2. "Param3D" : 3D parametric surfaces
   3. "Param3D_C" : 3D complex surfaces
   4. "Param4D" : 4D parametric surfaces
   5. "Param4D_C" : 4D complex surfaces
   6. "ParIso" : Isosurfaces + 3D parametric surfaces ("Iso3D" + "Param3D")

3. ### Mandatory Keys:

   For all objects types:

   `"Name"` | The script name is required and must be unique for each script. It's used to identify a script when stored in a collection file.
   `"Component"` | A mathematical object can be a composition of more than one mathematical equation. To help identify each component in a set of mathematically defined surfaces, you must give each component a name (not necessarily unique though).

   Mandatory Keys For "Iso3D":

   `"Fxyz"` | implicit equations
   `"Xmax", "Xmin", "Ymax", "Ymin", "Zmax", "Zmin"` | Isosurface definition domain limits.

   Mandatory Keys For "Param3D", "Param3D_C", "Param4D" and "Param4D_C":

   `"Fx","Fy","Fz"` | Parametric equations in the 3D space. `"Fw"` is required as the fourth dimension ("Param4D")
   `"Umax","Umin","Vmax","Vmin"` | Domain limits for u and v parameters.

4. ### Optional Keys:

   `"Funct"` | User defined functions. Example: `"Funct": ["Si=sinx", "Co=cos(y), "SC=Si(x,y,z,t)*Co(x,y,z,t)"]`
   `"Const"` | User defined Constantes. Example: `"Const": ["N=5", "P=pi/2", "E=N*P"]`
   `"Cnd"` | An implicit equation (according to x,y and z) to characterize a region in 3D space. The number of equations must be the same as the number of components. Example for an object including three components: `"Cnd":["x>0", "", "y<0"]` See the "Models_Intersection" script
   `"Grid"` | User defined grid values. The number of grid values is related to the number of components. Isosurfaces require one grid value for each component (ie: the same grid value for "x", "y" and "z") but parametric surfaces require two (ie one for "u" and one for "v") Example for a parametric surface with one component: `"Grid":["100", "150"]` See the "Models_Intersection" script
   `"Sliders"` | Sliders are useful for interactive modification of one or more parameter used in the script. Example:
       "Sliders": {
               "Name": ["N","R"],
               "Min": ["0","0"],
               "Max": ["50","50"],
               "Step": ["1","1"],
               "Position": ["10","16"]
           }
   `"Name"` : The parameters names (ie. N, R). `"Min", "Max"` : Minimum and maximum values for N and R. `"Step"` : Value used to adjust each parameter. `"Position"` : Saved values for each parameter (N, R)=(10, 16). Function used in the The_Dome_v1 script
   `"Description"` | You can give it another name (ie: "Infos" , ...) or delete it from the script (relevant for the user not the program). Example: `"Description": ["Blobby Torus by Abderrahman Taha 07/10/2019"]`
   `"Vect"` | (experimental) Define a set of variables (type double). For example, to create 10 variables, use: `"Vect":["10"]`

Any added new key will be simply ignored by MathMod unless it violates some syntax format rules for Objects in JSON

5. ### Texture and Pigment:

   1. "Texture": The texture generating function is evaluated over R^3 at each visible surface point of the model.
      MathMod support the RGB color model and it's alternative representation HSV (also known as HSB) .
      Accepted parameters for the texture of parametric surfaces : "x,y,z,u,v,i_indx,j_indx,indx,max_i,max_j,cmpId,t,Z"
      Accepted parameters for the texture of implicit surfaces : "x,y,z,t,cmpId,indx,x_step,y_step,z_step,max_ijk,x_sup,y_sup,z_sup,x_inf,y_inf,z_inf"
      Script sample:

          "Texture": {
             "Name": "Lines",
             "Noise": "NoiseW(x,y,z,(1),(2),(0))",
             "Colors": [
               "R=cos((x*x+y*y+z*z)*pi)",
               "G=cos((x*x+y*y+z*z)*pi)*cos(x*pi)",
               "B=sin(y*pi)*cos(x*pi)",
               "T=1"
          }

   2. "Pigment": Pigment definition.
      Most of the color patterns do not use abrupt color changes of just two or three colors like those in the brick, checker or hexagon patterns. They instead use smooth transitions of many colors that gradually change from one point to the next. The colors are defined in a pigment modifier that describes how the pattern blends from one color to the next.
      Each of the various pattern types available is in fact a mathematical function that takes any x, y, z location and turns it into a number. That number is used to specify what mix of colors to use from the color map: The pattern function gradient is evaluated and compared to the value of the first element in the "Vrgba" list (ie: "V=..."): if Gradient(x,y,z) is less than V[i] , color(x,y,z) = (R[i], G[i], B[i], A[i]) where "i" is the index of the "Color" object. Example :

          "Pigment": {
                   "Gradient": "3*atan((x*x*y*z)*pi)*cos(y*y*z*pi)",
                   "Name": "Pigment",
                   "Noise": "NoiseW(x,y,z,(1),(2),(0))",
                   "Colors": [
                       {
                           "Color": {
                               "Name": "Gold",
                               "Vrgba": ["V=0/10","R=9/10","G=7/10","B=1/10","A=1"]
                           }
                       },
                       {
                           "Color": {
                               "Name": "Red",
                               "Vrgba": ["V=3/10","R=1","G=1/10","B=31/100","A=1"]
                           }
                       },
                       {
                           "Color": {
                               "Name": "Green",
                               "Vrgba": ["V=5/10","R=1/10","G=7/10","B=1/10","A=1"]
                        }
                    }
               ]
          }

   3. Scripts examples:
      1. Models_Intersection
      2. CellNoiseSchwarz
      3. The_Dome_v1
      4. Pariso_02

6. ### Internal functions

   `NoiseP` | `NoiseP(x,y,z,Octaves,Lacunarity,Gain)` Perlin noise is a type of gradient noise developed by Ken Perlin in 1983 as a result of his frustration with the "machine-like" look of computer-generated imagery (CGI) at the time. He formally described his findings in a SIGGRAPH paper in 1985 called An image Synthesizer. `Octaves` : the number of levels of detail you want you Perlin noise to have. `Lacunarity` : number that determines how much detail is added or removed at each octave (adjusts frequency). `Gain` : number that determines how much each octave contributes to the overall shape (adjusts amplitude). Function used in the "Perlin_Schwarz" script
   `NoiseW` | `NoiseW(x,y,z,(A),(B),(C))` Worley noise is a noise function introduced by Steven Worley in 1996. In computer graphics it is used to create procedural textures, that is textures that are created automatically in arbitrary precision and do not have to be drawn by hand. Worley noise comes close to simulating textures of stone, water, or cell noise. `A, B, C` : Numbers between 0..2 Function used in the "CellNoiseSchwarz" script
   `f_hex_y` | `f_hex_y(x,y,z, P0)`. This is function forms a lattice of infinite boxes stretching along the z-axis. The fatness is controlled by the threshold value. These boxes are rotated 60 degrees around centers, which are 0.8660254 or cos(30) away from each other. This function is also useful as pigment function. `P0` : No effect (but the syntax requires at least one parameter) Function used in "Wall_Pattern_..." scripts (5 scripts in total)
   `fmesh` | `f_mesh1(x,y,z, P0, P1, P2, P3, P4)` The overall thickness of the threads is controlled by the isosurface threshold, not by a parameter. If you render a mesh1 with zero threshold, the threads have zero thickness and are therefore invisible. Parameters P2 and P4 control the shape of the thread relative to this threshold parameter. `P0` : Distance between neighboring threads in the x direction `P1` : Distance between neighboring threads in the z direction `P2` : Relative thickness in the x and z directions `P3` : Amplitude of the weaving effect. Set to zero for a flat grid `P4` : Relative thickness in the y direction Function used in the "Straw Basket_02" script
   `fhelix1` | `f_helix1(x,y,z, P0, P1, P2, P3, P4, P5, P6)` `P0` : Number of helixes - e.g. 2 for a double helix `P1` : Period - is related to the number of turns per unit length `P2` : Minor radius (major radius > minor radius) `P3` : Major radius `P4` : Shape parameter. If this is greater than 1 then the tube becomes fatter in the y direction `P5` : cross section type, (0.0 to 1.0 = square ... rounded to circle, over 2.0 to 3.0 = rounded to diamond and concave diamond) `P6` : Cross section rotation angle (degrees) Function use in "fhelix" and "Tori of helices" scripts
   `fhelix2` | `f_helix2(x,y,z, P0, P1, P2, P3, P4, P5, P6)`. Needs a negated function `P0` : Not used `P1` : Period - is related to the number of turns per unit length `P2` : Minor radius (minor radius > major radius) `P3` : Major radius `P4` : Not used `P5` : cross section type, (0.0 to 1.0 = square ... rounded to circle, over 2.0 to 3.0 = rounded to diamond and concave diamond) `P6` : Cross section rotation angle (degrees)
   `CmpId(0)` | Return the compound ID. Available only inside the "Funct" objects array. Example:
        "Funct": [
                   "Yx=(k1+k0*cos(u))*cos(v)*CmpId(0)",
                   "Yy=(k1+k0*cos(u))*sin(v)",
                   "Yz=k0*sin(u)",
                   ...
                 ]
   Used in the "Chained_Sinusoid" script.

7. ### Internal parameters

   - ### Isosurfaces

     `ThreadId` | Return the Thread ID. Example: To draw the isosurface portion calculated by the thread number 1
         "Fxyz": [" if(ThreadId=1, cos(x) + cos(y) + cos(z), 0)"]
     `max_ijk` | Refers to the Grid maximum value. Example:
         "Grid": ["150"] --> max_ijk=150
     `i_indx,j_indx,k_indx` | The index of the current voxel being evaluated

   - ### Isosurfaces textures

     `indx` | Return the current vertex index.
     `max_ijk` | Refers to the Grid maximum value. Example:
          "Grid": ["150"] --> max_ijk=150
     `x_sup,y_sup,z_sup,x_inf,y_inf,z_inf` | The isosurface definition domaine limits.
          "Xmin": ["10"] , "Xmax": ["pi"] --> x_inf=0 and x_sup=pi
     `x_step,y_step,z_step` |
          x_step=(x_sup-x_inf)/max_ijk
     `cmpId` | The compound ID.

   - ### Parametric surfaces

     `ThreadId` | Return the Thread ID

   - ### Parametric textures

     `i_indx , j_indx` | Return the current i and j indexes.
     `max_i , max_j` | Return the grid values. Example:
          "Grid": ["150","200"] --> In this case: max_i=150 and max_j=200
     `indx` | Return the current index (ie: indx=i*max_j+j)
     `cmpId` | Return the compound ID. Available only inside the "Texture" object. Example:
         "Texture": {
                "Colors": [
                    "R=if(cmpId = (130), (6/10), (7/10))",
                    "G=if((cmpId = 130), (1/10), (5/10))",
                    "B=if((cmpId = 130), (3/10), (0))",
                    "T=if((cmpId = 130), (7/10), (1))"
                ],
                "Name": "Gold",
                "Noise": ""
            }
     Used in the "BlackHole" script.

8. ### User Defined Variables

   `"Vect"` | (Experimental) Define a set of variables (type double). (Script example)
   `csd(N)` | (Experimental) Return the value of the variable at the index N. (Script example)
   `psh(N, val)` | (Experimental) Save the value "val" into the variable at index N. (Script example)

9. ### Supported operators and mathematical functions:

   The function string understood by MathMod is very similar (but not completely identical in all aspects) to mathematical expressions in the C/C++ languages. Arithmetic float expressions can be created from float literals, variables or functions using the following operators in this order of precedence:

   List of mathematic operators:

   `()` | expressions in parentheses first
   `A unit` | a unit multiplier (if one has been added)
   `A^B` | exponentiation (A raised to the power B)
   `-A` | unary minus
   `!A` | unary logical not (result is 1 if `int(A)` is 0, else 0)
   `A*B A/B A%B` | multiplication, division and modulo
   `A+B A-B` | addition and subtraction
   `A=B A<B A<=B A!=B A>B A>=B` | comparison between A and B (result is either 0 or 1)
   `A&B` | result is 1 if `int(A)` and `int(B)` differ from 0, else 0. Note: Regardless of the values, both operands are always evaluated. However, if the expression is optimized, it may be changed such that only one of the operands is evaluated, according to standard shortcut logical operation semantics.
   `A|B` | result is 1 if `int(A)` or `int(B)` differ from 0, else 0. Note: Regardless of the values, both operands are always evaluated. However, if the expression is optimized, it may be changed such that only one of the operands is evaluated, according to standard shortcut logical operation semantics.

   List of mathematical functions:

   `abs(A)` | Absolute value (magnitude) of A. With real numbers, if A is negative, returns -A otherwise returns A. With complex numbers, equivalent to `hypot(real(x),imag(x))`.
   `acos(A)` | Arc-cosine of A. Returns the angle, measured in radians, whose cosine is A.
   `acosh(A)` | Same as acos() but for hyperbolic cosine.
   `arg(A)` | Phase angle of complex number A. Equivalent to `atan2(imag(x),real(x))`.
   `asin(A)` | Arc-sine of A. Returns the angle, measured in radians, whose sine is A.
   `asinh(A)` | Same as asin() but for hyperbolic sine.
   `atan(A)` | Arc-tangent of (A). Returns the angle, measured in radians, whose tangent is A.
   `atan2(A,B)` | Principal arc-tangent of A/B, using the signs of the two arguments to determine the quadrant of the result. Returns the solution to the two expressions hypot(A,B)*sin(x)=A, hypot(A,B)*cos(x)=B. The return value is in range -pi to pi, inclusive.
   `atanh(A)` | Same as atan() but for hyperbolic tangent.
   `cbrt(A)` | Cube root of A. Returns a solution to expression pow(x,3)=A.
   `conj(A)` | Complex conjugate of A. Equivalent to `real(x) - 1i*imag(x)` or `polar(abs(x),-arg(x))`.
   `ceil(A)` | Ceiling of A. Returns the smallest integer not smaller than A. Rounds up to the next higher integer. E.g. -2.9, -2.5 and -2.1 are rounded to -2.0, and 2.9, 2.5 and 2.1 are rounded to 3.0.
   `cos(A)` | Cosine of A. Returns the cosine of the angle A, where A is measured in radians.
   `cosh(A)` | Same as cos() but for hyperbolic cosine.
   `cot(A)` | Cotangent of A. Equivalent to `1/tan(A)`.
   `eval(...)` | This a recursive call to the function to be evaluated. The number of parameters must be the same as the number of parameters taken by the function. Must be called inside `if()` to avoid infinite recursion.
   `exp(A)` | Exponential of A. Returns the value of e raised to the power A where e is the base of the natural logarithm, i.e. the non-repeating value approximately equal to 2.71828182846.
   `exp2(A)` | Base 2 exponential of A. Equivalent to `pow(2,A)`.
   `floor(A)` | Floor of A. Returns the largest integer not greater than A. Rounds down to the next lower integer. E.g. -2.9, -2.5 and -2.1 are rounded to -3.0, and 2.9, 2.5 and 2.1 are rounded to 2.0.
   `hypot(A,B)` | Euclidean distance function. Equivalent to `sqrt(A^2+B^2)`.
   `if(A,B,C)` | If int(A) differs from 0, the return value of this function is B, else C. Only the parameter which needs to be evaluated is evaluated, the other parameter is skipped; this makes it safe to use `eval()` in them.
   `imag(A)` | Return the imaginary part of complex number A. Equivalent to `abs(A)*sin(arg(A))`.
   `int(A)` | Rounds A to the closest integer. Equidistant values are rounded away from zero. E.g. -2.9 and -2.5 are rounded to -3.0; -2.1 is rounded to -2.0, and 2.9 and 2.5 are rounded to 3.0; 2.1 is rounded to 2.0.
   `log(A)` | Natural (base e) logarithm of A. Returns the solution to expression exp(x)=A.
   `log2(A)` | Base 2 logarithm of A. Equivalent to `log(A)/log(2)`.
   `log10(A)` | Base 10 logarithm of A.
   `max(A,B)` | If A>B, the result is A, else B.
   `min(A,B)` | If A<B, the result is A, else B.
   `real(A)` | Return the real part of complex number A. Equivalent to `abs(A)*cos(arg(A))`.
   `polar(A,B)` | Returns a complex number from magnitude A, phase angle B (in radians). Equivalent to `real(A)*(cos(real(B))+1i*sin(real(B)))`.
   `sec(A)` | Secant of A. Equivalent to `1/cos(A)`.
   `sin(A)` | Sine of A. Returns the sine of the angle A, where A is measured in radians.
   `sinh(A)` | Same as sin() but for hyperbolic sine.
   `sqrt(A)` | Square root of A. Returns a solution to expression pow(x,2)=A.
   `tan(A)` | Tangent of A. Returns the tangent of the angle A, where A is measured in radians.
   `tanh(A)` | Same as tan() but for hyperbolic tangent.
   `trunc(A)` | Truncated value of A. Returns an integer corresponding to the value of A without its fractional part. E.g. -2.9, -2.5 and -2.1 are rounded to -2.0, and 2.9, 2.5 and 2.1 are rounded to 2.0.

## Configuration file

"mathmodconfig.js" file is the main source for MathMod's parameters settings.
MathMod uses an integrated configuration file but it can generate a copy for you when needed. Here is how:

1. Create a new folder (exemple: "myfolder")
2. Open a command line terminal and execute : `mathmod MyfolderPath/myfolder` (replace "MyfolderPath" by the complete path to "myfolder")
3. MathMod will generate three files in "myfolder": "mathmodconfig.js", "mathmodcollection.js" and "advancedmodels.js"
4. Close MathMod and add your modifications to "mathmodconfig.js". The next time you execute `mathmod MyfolderPath/myfolder` , MathMod will use "mathmodcollection.js" in myfolder as it's configuration file and "mathmodcollection.js" as it's integrated scripts collection.

`"Parameters": { "IsoMaxGrid": 500, "InitIsoGrid": 40, "ParMaxGrid": 5000, "InitParGrid": 50 }` | Maximum and current grid value setting for iso/parametric surfaces. "IsoMaxGrid" and "ParMaxGrid" can be set from the GUI (See attached image)
`"StartOptions": { "Model": "CloseIso_1" }` | Set the first script to be rendered when MathMod starts (by default it's the "CloseIso_1" script)
`"Localization": { "AutomaticDetection": true, "DotSymbol": "." }` |
`"OpenGlConfig": { "GL_SPECULAR": [50, 50, 50, 100], "GL_SHININESS": 110 }` | OpenGL setting for MathMod's 3D viewer window. OpenGL settings can also be modified from the GUI (see attached image)
`"ThreadsConfig": { "AutoDetect": true, "ThreadsNumber": 8, "MinThreadsNumber": 1, "MaxThreadsNumber": 64 }` | image
`"WindowPosition": { "ControlX": 20, "ControlY": 20, "GlwinX": 580, "GlwinY": 20 }` |
`"WindowSize": { "ControlH": 750, "ControlW": 538, "GlwinH": 750, "GlwinW": 750 }` |
`"CalculFactorConfig": { "FactX": 4, "FactY": 4, "FactZ": 4 }` | Only for isosurfaces: sets a cube of (4*4*4) points to be calculated "at once".
`"Styles": { "PredefinedStyle": [ "Default", "Fusion", "Windows","WindowsXp"], "UsedStyle": "Fusion" }` | By default, MathMod uses the dark mode "Fusion". image
`"Themes": { "PredefinedThemes": [ "Default", "Dark", "MyTheme"], "UsedTheme": "Dark", "MyTheme": { "Window":[53,53,53], "WindowText":[255, 255, 255], "Base":[15,15,15], "AlternateBase":[53,53,53], "ToolTipBase":[255, 255, 255], "ToolTipText":[255, 255, 255], "Text":[2, 2, 255], "Button":[53,53,53], "ButtonText":[255, 255, 255], "BrightText":[255, 0, 0], "Highlight":[142,45,197], "HighlightedText":[0, 0, 0] } }` | By default, MathMod uses the dark mode "Fusion". To test other themes, use the "look And feel" page in the "Configurations Options" window. image

## Animations and Morph transitions

1. ## Morph effect

   MathMod is home to many interesting animations and transitions. The morph effect take place with the use of the "t" parameter and the morph effect activation (and deactivation) with "CtRl+p". The Morph transition lets you create a seamless object animation from one "t" time parametr value to another. Example:

       {
           "Param3D": {
               "Description": ["Sinus Animation by Abderrahman Taha"],
               "Name": ["SinusPar"],
               "Component": ["Sinus"],
               "Fx": ["u"],
               "Fy": ["v"],
               "Fz": ["-sin(-t+3*pi*((u)^2+(v)^2))/10"],
               "Umax": ["1"],
               "Umin": ["-1"],
               "Vmax": ["1"],
               "Vmin": ["-1"]
           }
       }

2. ## Rotation

   The rotation animation activation (and deactivation) take place with "CtRl+a". Also, the "Rotations Controls" section helps set the axe and speed of the rotation.

3. ## Making animated GIF or videos

   This video explain how to create animated GIF with MathMod and Gimp.
   See also some animated GIF made with MathMod on Reddit and gfycat

## MathMod's GUI Reference

## Menu Items

1. ### The Project Menu

   Project Menu

2. ### The Options Menu

   Options Menu

3. ### The Export Menu

   Export Menu

4. ### The Help Menu

## Tabbed pages

1. ### The "Model Details" page

   Isosurface details page
   3D Parametric details page
   4D Parametric details page
   Pariso object details page

2. ### The "Script Edit" page

   Script Edit page

3. ### The "View Controls" page

   CND page Rotation page Time Step page Export Scal page

4. ### The "Appearance" page

   Colors page
   Texture page
   Specular page
   Ambient page
   Diffuse page
   Threads page

5. ### The "Sliders" page

## Scripts Examples

1.     {
           "Iso3D": {
               "Description": ["Models Intersection by Abderrahman Taha 20/02/2020"],
               "Name": ["Models_Intersection"],
               "Component": ["Schwarz","Plan"],
               "Cnd": ["(x-y-(3/2)*z<0)",""],
               "Fxyz": ["cos(x-4*sin(t*pi))+cos(y)+cos(z)","x-y-(3/2)*z-(1/100)"],
               "Grid": ["30","20"],
               "Xmax": ["4+4*sin(t*pi)","6"],
               "Xmin": ["-4+4*sin(t*pi)","-6"],
               "Ymax": ["4","6"],
               "Ymin": ["-4","-6"],
               "Zmax": ["4","6"],
               "Zmin": ["-4","-6"]
           }
       }

   See attached image

2.         {
               "Iso3D": {
                   "Description": ["CellNoiseSchwarz by Abderrahman Taha 08/03/2020"],
                   "Name": ["CellNoiseSchwarz"],
                   "Component": ["Schwarz"],
                   "Fxyz": ["cos(x)+cos(y)+cos(z)-NoiseW(x,y,z,(1),(2),(0))"],
                   "Xmax": ["4"],
                   "Xmin": ["-4"],
                   "Ymax": ["4"],
                   "Ymin": ["-4"],
                   "Zmax": ["4"],
                   "Zmin": ["-4"
                   ]
               },
               "Texture": {
                   "Colors": ["R=cos(x)*sin(z)+3/10","G=sin(x)*cos(y)+3/10","B=sin(y)*cos(z)+3/10","T=1"],
                   "Name": "Lines3",
                   "Noise": "NoiseW(x,y,z,(1),(2),(0))"
               }
           }

   See attached image

3.     {
           "Iso3D": {
               "Description": ["The Dome by Abderrahman Taha 10/08/2018"],
               "Name": ["The_Dome_v1"],
               "Component": ["The_Dome_01"],
               "Const": ["c=1/1000","Th=6/10","N=10","R=16"],
               "Funct": [
               "Scherk=sinh(x)*sinh(y)-4*sin(z)",
               "Scherk2=Scherk(N*atan2(x,sqrt(y*y+z*z)),(sqrt(x*x+y*y+z*z)-R),N*atan2(z,y),t)",
               "IsoExterior=Scherk2(x,y,z,t)",
               "DFx=((IsoExterior(x+c,y,z,t)-IsoExterior(x,y,z,t))/c)",
               "DFy=((IsoExterior(x,y+c,z,t)-IsoExterior(x,y,z,t))/c)",
               "DFz=((IsoExterior(x,y,z+c,t)-IsoExterior(x,y,z,t))/c)",
               "Rapp=x/sqrt(x*x+y*y+z*z)",
               "Iso3=(IsoExterior(x- Th*Rapp(DFx(x,y,z,t),DFy(x,y,z,t),DFz(x,y,z,t),t),y-Th*Rapp(DFy(x,y,z,t),DFx(x,y,z,t),DFz(x,y,z,t),t),z-Th*Rapp(DFz(x,y,z,t),DFx(x,y,z,t),DFy(x,y,z,t),t), t))",
               "Iso2=(IsoExterior(x+ Th*Rapp(DFx(x,y,z,t),DFy(x,y,z,t),DFz(x,y,z,t),t),y+Th*Rapp(DFy(x,y,z,t),DFx(x,y,z,t),DFz(x,y,z,t),t),z+Th*Rapp(DFz(x,y,z,t),DFx(x,y,z,t),DFy(x,y,z,t),t), t))",
               "TickIsoExterior=(Iso2(x,y,z,t)*Iso3(x,y,z,t))"
               ],
               "Fxyz": ["if((sqrt(x*x+y*y+z*z)-24) < (0),TickIsoExterior(z,y,x,t),(1))"],
               "Xmax": ["27"],
               "Xmin": ["-27"],
               "Ymax": ["27"],
               "Ymin": ["-27"],
               "Zmax": ["18"],
               "Zmin": ["-18"]
           },
           "Sliders": {
               "Max": ["50","50"],
               "Min": ["0","0"],
               "Name": ["N","R"],
               "Position": ["10","16"],
               "Step": ["1","1"]
           },
           "Texture": {
               "Colors": ["R=(7/10)*(cos(x)*cos(y)*cos(z))^(1/10)","G=(7/10)","B=(7/10)","T=1"],
               "Name": "Lines",
               "Noise": ""
           }
       }

   See attached image

4.     {
           "Param3D_C": {
               "Description": ["Complex3D_01 by Abderrahman Taha 28/04/2021"],
               "Description": ["Complex function: f(z)=2*z^2+ 2*z +2"],
               "Name": ["Complex3D_01"],
               "Component": ["complex"],
               "Fx": ["u"],
               "Fy": ["v"],
               "Fz": ["abs(2*z*z+2*z+2)/3"],
               "Umax": ["1"],
               "Umin": ["-2"],
               "Vmax": ["2"],
               "Vmin": ["-2"]
           }
       }

   See attached image

5.     {
           "Param4D_C": {
               "Description": ["Complex_Saddle by Abderrahman Taha 28/04/2021"],
               "Component": ["Saddle"],
               "Name": ["Complex4D_Saddle"],
               "Fx": ["u"],
               "Fy": ["v"],
               "Fz": ["real(z*z)/2"],
               "Fw": ["imag(z*z)/2"],
               "Umax": ["2"],
               "Umin": ["-2"],
               "Vmax": ["2"],
               "Vmin": ["-2"]
           }
       }

   See attached image

6.     {
           "Name": "Pariso_02",
           "ParIso": [
               {
                   "Param3D": {
                       "Description": ["Blobby Torus by Abderrahman Taha 07/10/2019"],
                       "Name": ["Blobby_Torus"],
                       "Component": ["BlobbyTorus"],
                       "Funct": ["G1=(8+(sin(2*(u-v+t+sin(v-u)))+3)*cos(u))*cos(v)","G2=(8+(sin(2*(u-v+t+sin(v-u)))+3)*cos(u))*sin(v)","G3=((sin(2*(u-v+t+sin(v-u)))+3)*sin(u))"],
                       "Fx": ["-G1(u,v,t)"],
                       "Fy": ["G2(u,v,t)"],
                       "Fz": ["G3(u,v,t)-10"],
                       "Grid": ["100","200"],
                       "Umax": ["2*pi"],
                       "Umin": ["0"],
                       "Vmax": ["2*pi"],
                       "Vmin": ["0"]
                   },
                   "Texture": {
                       "Colors": ["R= if((abs(7*u)%pi/2 & abs(7*v)%pi/3),(6/10),1) ","G= if((abs(7*u)%pi/2| abs(7*v)%pi/3),(8/10),(4/10)) ","B= if((abs(7*u)%pi/2| abs(7*v)%pi/3),(6/10),(1/10)) ","T=1"],
                       "Name": "Candy",
                       "Noise": "1"
                   }
               },
               {
                   "Iso3D": {
                       "Description": ["Models Intersection by Abderrahman Taha 04/11/2019"],
                       "Name": ["Models_Intersection"],
                       "Component": ["Schwarz","Plan"],
                       "Cnd": ["(x-y-(3/2)*z<0)",""],
                       "Fxyz": ["cos(x-4*sin(t*pi))+cos(y)+cos(z)","x-y-(3/2)*z-(1/100)"],
                       "Xmax": ["4+4*sin(t*pi)","6"],
                       "Xmin": ["-4+4*sin(t*pi)","-6"],
                       "Ymax": ["4","6"],
                       "Ymin": ["-4","-6"],
                       "Zmax": ["4","6"],
                       "Zmin": ["-4","-6"]
                   }
               }
           ]
       }

   See attached image

7.     {
           "Iso3D": {
               "Description": ["Arena_02 using user defined variables by Abderrahman Taha 27/06/2020"],
               "Name": ["Arena_02"],
               "Component": ["Arena"],
               "Const": ["c=1/10000",
                   "th=6/10",
                   "N=10"],
               "Vect": ["4"],
               "Funct": ["Scherk=sinh(x)*sinh(y)-4*sin(z)",
                   "IsoExterior =Scherk(x,sqrt(y*y+z*z)-(16),N*atan2(z,y),t)",
                   "DFx=((IsoExterior(x+c,y,z,t)-IsoExterior(x,y,z,t))/c)",
                   "DFy=((IsoExterior(x,y+c,z,t)-IsoExterior(x,y,z,t))/c)",
                   "DFz=((IsoExterior(x,y,z+c,t)-IsoExterior(x,y,z,t))/c)",
                   "Rapp=(th/sqrt(x*x+y*y+z*z))",
                   "ThickIsoExterior=  psh(0, DFx(x,y,z,t)) * psh(1, DFy(x,y,z,t)) * psh(2, DFz(x,y,z,t)) * (psh(3, Rapp(csd(0) , csd(1) , csd(2),t)))  * (IsoExterior(x-csd(0)*csd(3) ,y-csd(1)*csd(3),z-csd(2)*csd(3),t))*(IsoExterior(x+csd(0)*csd(3) ,y+csd(1)*csd(3),z+csd(2)*csd(3),t))"],
               "Fxyz": ["if((sqrt(x*x+y*y+z*z) - 27) < 0 & abs(x) < (99/10) ,ThickIsoExterior(x,y,z,t), 1)"],
               "Xmax": ["10"],
               "Xmin": ["-10"],
               "Ymax": ["28"],
               "Ymin": ["-28"],
               "Zmax": ["28"],
               "Zmin": ["-28"]
           }
       }

   See attached image

References:

1. Solid_texturing
2. Povray documentation
3. Povray Internal functions
4. Isosurfaces tutorial
5. Povray scripts