# Math and Logic

Unresolved directive in index.adoc - include::../../partials/navbar.html[]

> Only mathematics and mathematical logic can say as little as the physicist means to say.

— Bertrant Russel

## Math and Logic

### `AndIsFalse()`

`AndIsFalse(Expressions)`

- Expressions, array, an array of Boolean expressions.

`AndIsFalse()` takes an array of Boolean expressions like in the example below. If all are indeed false, it returns true, if one or more are true, the result is false.

    echo(AndIsFalse([2 > 4, 5 < 0, "ed" == "ted"]));
    echo(AndIsFalse([2 > 4, 5 < 0, "ed" == "ed"]));

    ECHO: true
    ECHO: false

### `AndIsTrue()`

`AndIsTrue(Expressions)`

- Expressions, array, an array of Boolean expressions.

`AndIsTrue()` takes an array of Boolean expressions like in the example below. If all are indeed true, it returns true, if one or more are false, the result is false.

    echo(AndIsTrue([2 < 4, 5 > 0, "ed" == "ed"]));
    echo(AndIsTrue([2 < 4, 5 > 0, "ed" == "ted"]));

    ECHO: true
    ECHO: false

### `BinomialCoefficient()`

`BinomialCoefficient(N,K)`

- N, integer, binomial power (1 + x)n (and row in Pascal’s triangle)

- K, integer, the xk term in the expansion (and element in the row)

`BinomialCoefficient(N,K)` is the coefficient of the xk term in the polynomial expansion of the binomial power (1 + x)n.

If that’s clear as mud because math wasn’t your favourite subject, don’t worry about it. You’ll never need it; it’s only here because `GBezierPoint()` uses it, and if anything happens anywhere in The GHOUL, I aim to document it. Really, I mean it, don’t worry.

### `Clip()`

`Clip(Value,Min,Max)`

- Value, value to be 'clipped'.

- Min, lower clipping limit.

- Max, upper clipping limit.

`Clip()` allows you to write `Baz=Clip(Foo,0,10)` instead of `Baz=min(max(Foo,0),10)`. It’s a little trivial, I know, but I like the looks better and the code reads easier, in my opinion.

    Foo=12;
    Baz=Clip(Foo,0,10);
    echo(Baz);

    ECHO: 10

### `Deg()`

`Deg(Radians)`

- Radians, radians to be converted.

`Deg()` converts allows you to write `Baz=Deg(3.63)` instead of `Baz=3.63/Tau*360`. It’s also a bit trivial, I know, but it definitely makes for prettier code.

    Foo=3.63;
    Baz=Deg(Foo);
    echo(Baz);

    ECHO: 207.984

### `Dex()`

`Dex(Index,Max=$len)`

- Index, integer, counter to be mapped onto [0:Max].

- Max, integer, upper limit (exclusive) for the mapped result, usually `len()` of the array under consideration.

There are many ways to 'circular address' an array, `Dex()` is probably the most elegant in The GHOUL. When `Dex()` is used multiple times on the same Array, define `$len=len(Array);` and use it like `Array[Dex(Index)]`.

    Index=Map(Anydex,0,6);
    Anydex  :  -2 -1  0  1  2  3  4  5  6  7  8...
    Index   :   4  5  0  1  2  3  4  5  0  1  2...

### `Factorial()`

`Factorial(Int)`

- Int, integer to calculate the factorial of.

`Factorial()`, unsurprisingly, calculates the factorial.

    echo(Factorial(5));

    ECHO: 120

### `GCDA()`

`GCDA(Array)`

- Array, array of values to calculate the greatest common divisor of.

`GCDA()`, calculates the greatest common divisor of the values in Array. I couldn’t bring myself to call it 'GreatestCommondDivisorArray'; there is a limit (it’s 25 at the moment).

    echo(GCDA([32,12,56]));

    ECHO: 4

### `GreatestCommonDivisor()`

`GreatestCommonDivisor(Value1,Value2)`

- Value1,Value2, values to calculate the greatest common divisor of.

`GreatestCommonDivisor()`, calculates the greatest common divisor of two values. It does this by replacing the higher value with the modulo of the two until that reaches 0, the remaining value is then the GCD. `GreatestCommondDivisor()` is the contender for the longest function name in The GHOUL, the current holder of the title is `SearchPrintableCharacters()`, like I already said: there is a limit.

| If you’d rather not have 21-letter function names in your code, there’s `GCD()`; a shorter-but-not-so-descriptive alias for `GreatestCommondDivisor()`

    echo(GreatestCommonDivisor(12,31));

    /*
      The iterations are:
      31-12
      12-7
      7-5
      5-2
      2-1
      1-0
    */

    ECHO: 1

### `Intermediate()`

`Intermediate(Start,End,Frac)`

- Start, value, tuple or array.

- End, value, tuple or array.

- Frac, a fraction 0=<Frac=<1 (although 0 and 1 wouldn’t make much sense).

`Intermediate()` returns the intermediate value, tuple or array between Start and End at Frac of the difference from Start. It can be used for an intermediate curve, point, or even a color definition or a single value. It is clever enough to return values in the correct type.

    echo(Intermediate([[0,0],[10,10]],[[5,10],[30,20]],0.4));
    echo(Intermediate([10,10],[30,20],0.4));
    echo(Intermediate([10],[20],0.4));
    echo(Intermediate(10,20,0.4));

    ECHO: [[2, 4], [18, 14]]
    ECHO: [18, 14]
    ECHO: [14]
    ECHO: 14

    /* The code for image above:  */

    Start=[[0,0,0],[4,4,0],[3,8,0]];
    End=[[0,4,10],[2,8,8],[5,10,6]];

    ShowCurve(Start,0.2,Connect=true);
    ShowCurve(End,0.2,Connect=true);

    color(Intermediate(RED,BLU,$t))
    ShowCurve(Intermediate(Start,End,$t),0.2,Connect=true);

### `Interpolate()`

`Interpolate(Domain,Range,Input)`

- Domain, tuple, value pair of Min and Max input values [Min,Max].

- Range, tuple, value pair of Min and Max result values [Min,Max].

- Input, value, on, or outside of Domain.

`Interpolate()` returns the value from Range, proportionally corresponding to the position of Input on Domain. If Input lies outside of Domain, `Interpolate()` effectively becomes 'Extrapolate()', which, for that reason, doesn’t exist…​

    echo(Interpolate([0,10],[80,100],3.2));
    echo(Interpolate([0,10],[80,100],-2));

    ECHO: 86.4
    ECHO: 76

### `InterVertex()`

`InterVertex(Vertex1,Vertex2,Coordinate)`

- Vertex1, Vertex2, 3D vertices.

- Coordinate, single coordinate of the desired vertex. Only one of the X,Y or Z coordinate must be given in this format: [undef,1,undef], i.e., two out of three must be undef.

`InterVertex()` returns a vertex that is situated on the line through Vertex1 and Vertex2, based on one known coordinate.

    P1=[0,0,0];
    P2=[5,2,1];
    Coord=1;

    echo(InterVertex(P1,P2,[undef,Coord,undef]));

    ECHO: [2.5,1,0.5]

`InterVertex2()` accepts a slighly different syntax and allows you to simply assign a value to x, y or z:

    P1=[0,0,0];
    P2=[5,2,1];

    echo(InterVertex2(P1,P2,y=1));

    ECHO: [2.5,1,0.5]

### `Is…​()`

`Is…​(I)`

- I, scalar, fraction or integer to be analised.

IsMath.scad contains several functions that test numbers and return either true or false.:

IsEven(I) | true if I is an even integer.
IsOdd(I) | true if I is an odd integer.
IsInterger(I) | true if I is an integer.
IsNotInterger(I) | true if I is not an integer.
IsFraction(I) | true if I is a fraction 0<I<1.
IsNumber(I) | true if I is any kind of number.
IsPositive | true if I is a positive number 0<I.
IsNegative | true if I is a negative number I<0.

### `KroneckerDelta()`

`KroneckerDelta(I,J)`

- I, J, usually integers, usually positive.

`KroneckerDelta()` returns 1 when I==J and 0 otherwise. Normally I and J are positive integers, but they could be anything really…​

    I=[2,3,4]:
    I=[2,3,4]:

    // Instead of echo(I==J?1:0) you can write:
    echo(KroneckerDelta(I,J));

    ECHO: 1

### `LCMA()`

`LCMA(Array)`

- Array, array of values to calculate the least common multiple of.

`LCMA()`, calculates the least common multiple of the values in Array. I couldn’t bring myself to call it 'LeastCommondMultipleArray'; for much the same reason as stated at `GCDA()`.

    echo(LCMA([32,12,56]));

    ECHO: 672

### `LeastCommonMultiple()`

`LeastCommonMultiple(Value1,Value2)`

- Value1, Value2, integers, val to find the least common multiple of.

### `Map()`

`Map(Value,Min,Max)`

- Value, integer to map.

- Min, integer, lower mapping limit.

- Max, integer, upper mapping limit.

Circular map Value onto an interval so that 0 maps onto the lower limit of the interval (0→Min) and the upper limit maps back onto the lower (circular map).

Here’s how to map any value onto the interval [4:8]. Regardless of Value, Result stays within the interval.

    Result=Map(Value,4,8);
    Result  :    7   4   5   6   7   4   5...
    Value   :   11  12  13  14  15  16  17...

| The upper limit is never reached! In a similar sense to `Array[len(Array)] == undef`, the upper limit falls just outside the interval, however, because `Map()` is circular, it maps the upper limit back onto the lower limit.

Here’s how to 'circular address' an array that has `len()` 6, and thus valid indices of [0:5]. Regardless of the value of Anydex, Index stays within the valid range of array indices.

    Index=Map(Anydex,0,6);
    Anydex  :  -2 -1  0  1  2  3  4  5  6  7  8...
    Index   :   4  5  0  1  2  3  4  5  0  1  2...

This has significant advantages over `Array[Anydex%6]` because that construct is lost when Anydex<0. Now you can address Anydex=-2 and 103 or -34.

| Map.scad also contains a handful of shortcuts for common Value ranges, such as `Map360()`, `Map60()`, `Map24()`, `Map12()` and `MapTau()`, they all have 0 as a lower limit. Finally, there’s `MapDex()` for circular addressing of arrays.

### `MCeil()`

`MCeil(Value,Factor)`

- Value, scalar, value to be rounded up.

- Factor, scalar, rounding multiplier.

`MCeil()` rounds Value up to the nearest multiple of Factor.

    echo(MCeil(5.31,0.25));

    ECHO: 5.5

### `MFloor()`

`MFloor(Value,Factor)`

- Value, scalar, value to be rounded down.

- Factor, scalar, rounding multiplier.

`MFloor()` rounds Value down to the nearest multiple of Factor.

    echo(MCeil(5.31,0.25));

    ECHO: 5.25

### `Mod()`

`Mod(Value,Modulus)`

- Value, scalar, value to be reduced.

- Modulus, integer, modulus.

`Mod()` is identical to the native OpenSCAD modulo operator `%`. It’s just here because, well, I’m not really sure to be honest. It doesn’t add anything, maybe it looks good? Oh, well…​

| Mod.scad also contains a handful of shortcuts for common Value values, such as `Mod1()`,`Mod2()`,`Mod360()` and `ModTau()`

    echo(Mod360(402));

    ECHO: 42

### `MRound()`

`MRound(Value,Factor)`

- Value, scalar, value to be rounded.

- Factor, scalar, rounding multiplier.

`MRound()` rounds Value to the nearest multiple of Factor.

    echo(MRound(5.31,0.25));

    ECHO: 5.25

### `NDecimal()`

`NDecimal(Value,N)`

- Value, scalar, value to be processed.

- N, integer, decimal index.

`NDecimal()` returns the decimal at the N position in Value. N is 0-based.

    echo(NDecimal(12.1234567,3));

    ECHO: 4

### `NearestEven()`

`NearestEven(Value)`

- Value, scalar.

`NearestEven()` returns the nearest even integer to Value. It is an alias for `MFloor(Value+1,2)`. When Value is an odd integer, the nearest larger, i.e., more positive, even integer is returned.

    echo(NearestEven(31.01));
    echo(NearestEven(32.99));
    echo(NearestEven(33));

    ECHO: 32
    ECHO: 32
    ECHO: 34

### `NearestOdd()`

`NearestOdd(Value)`

- Value, scalar.

`NearestOdd()` returns the nearest odd integer to Value. It is an alias for `MFloor(Value,2)+1`. When Value is an even integer, the nearest larger, i.e., more positive, odd integer is returned.

    echo(NearestOdd(30.01));
    echo(NearestOdd(31.99));
    echo(NearestOdd(32));

    ECHO: 31
    ECHO: 31
    ECHO: 33

### `NotZero()`

`NotZero(Value)`

- Value, scalar, value to be processed.

`NotZero()` prevents 0 values that may break certain functions such as affine transformations, by replacing Value only when it is 0, with Thought, which is defined in Config,scad as 1/8192, or barely anything at all.

    echo(NotZero(0));

    ECHO: 0.00012207

### `OrIsFalse()`

`OrIsFalse(Expressions)`

- Expressions, array, an array of Boolean expressions.

`OrIsFalse()` takes an array of Boolean expressions like in the example below. If one is false, it returns true, if none are false, the result is false. It is an alias for `!AndIsTrue()`.

    echo(OrIsFalse([2 < 4, 5 > 0, "ed" == "ted"]));
    echo(OrIsFalse([2 < 4, 5 > 0, "ed" == "ed"]));

    ECHO: true
    ECHO: false

### `OrIsTrue()`

`OrIsTrue(Expressions)`

- Expressions, array, an array of Boolean expressions.

`OrIsTrue()` takes an array of Boolean expressions like in the example below. If one is true, it returns true, if none are true, the result is false. It is an alias for `!AndIsFalse()`.

    echo(OrIsTrue([2 > 4, 5 < 0, "ed" == "ed"]));
    echo(OrIsTrue([2 > 4, 5 < 0, "ed" == "ted"]));

    ECHO: true
    ECHO: false

### `Rad()`

`Rad(Degrees)`

- Degrees, degrees to be converted.

`Rad()` allows you to write `Baz=Rad(65)` instead of `Baz=65/360*Tau`. It’s also a bit trivial, I know, but it definitely makes for prettier code.

    Foo=65;
    Baz=Rad(Foo);
    echo(Baz);

    ECHO: 1.13446