Math in Bitbybit
View Full Source & Details on GitHub
bitbybit.math works on plain numbers. Many of its functions wrap JavaScript's own Math, so that Rete and Blockly can use them as nodes and blocks; in TypeScript you can call either.
Angles are in radians
sin, cos and tan take an angle in radians, and asin, acos and atan give one. Most angles people type are in degrees, so convert at the boundary with degToRad and radToDeg: 180 degrees is pi(), about 3.14159.
Arithmetic
add,subtract,multiply,divideandpowerwork onfirstandsecond, in that order: subtract gives first minus second, power gives first to the power of second. Dividing by 0 givesInfinity, as in JavaScript.modulusgives the remainder of a division; its sign follows the first number, so -7 modulus 3 is -1.twoNrOperationdoes any of add, subtract, multiply, divide, power or modulus, chosen byoperation.abs,negate,sign(-1, 0 or 1),sqrt(NaNfor a negative number),ln,log10,exp(e to the power) andtenPow(10 to the power) work on one number.oneNrOperationdoes any one-number operation, chosen byoperation: the ones above, the rounding and trigonometric functions and the angle conversions.evalArithmeticworks out an expression typed as text, such as(3 + 2) / 4, with numbers,+,-,*,/and parentheses. The library parses it itself and never runs it as JavaScript, so it is safe with text a user typed. Anything else in the text stops the script with an error.
Rounding and formatting
roundrounds to the nearest whole number, with halves rounding up;floorrounds down andceilrounds up.roundToDecimalsrounds todecimalPlacesdigits after the point.roundAndRemoveTrailingZerosdoes the same and also cleans floating-point noise, so 1.320000001 becomes 1.32.fractkeeps the part after the decimal point, measured up from the whole number below, so -2.3 gives 0.7.toFixedgives text, not a number, with exactlydecimalPlacesdigits and trailing zeros kept: 5 with 3 places is"5.000".
Numbers to start from
numberpasses a number through unchanged, so a value can be set once in Rete or Blockly, named and reused.pigives pi.randomgives a number from 0 up to, but not including, 1.randomNumbergives one betweenlowandhigh, andrandomNumbersgivescountof them. Each call gives new values.
Blending, easing and ranges
These are the building blocks of animation and parametric variation.
lerpblends fromstarttoendby a fractiont: 0 gives the start, 1 the end, and atoutside 0 to 1 continues past them.inverseLerpgoes the other way and gives thetof a value.remapmaps a number from one range onto another, keeping its relative position: 5 in 0 to 10 becomes 50 in 0 to 100.easemapsxfrom 0 to 1 ontomintomaxalong an easing curve, so the change speeds up or slows down instead of being even.easenames the curve: aneaseIn...curve starts slowly,easeOut...ends slowly andeaseInOut...does both, in the Sine, Quad, Cubic, Quart, Quint, Expo, Circ, Elastic, Back and Bounce families.smoothstepturns a value from 0 to 1 into a gentle S-curve, after clamping it to that range.clampkeeps a number betweenminandmax.wrapcycles a number into the range fromminup tomax, so 370 in 0 to 360 gives 10. Unlike a plain modulus it handles negative numbers.pingPongbounces a growingtback and forth between 0 andlength.moveTowardsmovescurrenttowardtargetby at mostmaxDelta, without overshooting.
Here a fraction, as a slider gives it, is remapped to a height between 1 and 6 and rounded to one decimal, and the height sizes a column:
- Rete
- Blockly
- TypeScript
Script Source (rete)
{
"id": "rete-v2-json",
"nodes": {
"height": {
"id": "height",
"name": "bitbybit.math.remap",
"customName": "remap",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 0.7,
"fromLow": 0,
"fromHigh": 1,
"toLow": 1,
"toHigh": 6
},
"inputs": {},
"position": [
40,
40
]
},
"rounded": {
"id": "rounded",
"name": "bitbybit.math.roundToDecimals",
"customName": "round to decimals",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"number": 1.123456,
"decimalPlaces": 1
},
"inputs": {
"number": {
"connections": [
{
"node": "height",
"output": "result",
"data": {}
}
]
}
},
"position": [
460,
40
]
},
"column": {
"id": "column",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "cylinder",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 0.5,
"height": 2,
"center": [
0,
0,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {
"height": {
"connections": [
{
"node": "rounded",
"output": "result",
"data": {}
}
]
}
},
"position": [
880,
40
]
}
},
"modules": {}
}
Script Source (blockly)
<xml xmlns="https://developers.google.com/blockly/xml"><block type="bitbybit.draw.drawAnyAsyncNoReturn" x="40" y="40"><value name="Entity"><block type="bitbybit.occt.shapes.solid.createCylinder"><value name="Radius"><block type="math_number"><field name="NUM">0.5</field></block></value><value name="Height"><block type="bitbybit.math.roundToDecimals"><value name="Number"><block type="bitbybit.math.remap"><value name="Number"><block type="math_number"><field name="NUM">0.7</field></block></value><value name="FromLow"><block type="math_number"><field name="NUM">0</field></block></value><value name="FromHigh"><block type="math_number"><field name="NUM">1</field></block></value><value name="ToLow"><block type="math_number"><field name="NUM">1</field></block></value><value name="ToHigh"><block type="math_number"><field name="NUM">6</field></block></value></block></value><value name="DecimalPlaces"><block type="math_number"><field name="NUM">1</field></block></value></block></value><value name="Center"><block type="bitbybit.point.pointXYZ"><value name="X"><block type="math_number"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number"><field name="NUM">0</field></block></value><value name="Z"><block type="math_number"><field name="NUM">0</field></block></value></block></value><value name="Direction"><block type="bitbybit.vector.vectorXYZ"><value name="X"><block type="math_number"><field name="NUM">0</field></block></value><value name="Y"><block type="math_number"><field name="NUM">1</field></block></value><value name="Z"><block type="math_number"><field name="NUM">0</field></block></value></block></value><value name="Angle"><block type="math_number"><field name="NUM">360</field></block></value><value name="OriginOnCenter"><block type="logic_boolean"><field name="BOOL">FALSE</field></block></value></block></value></block></xml>
Script Source (typescript)
const height = bitbybit.math.remap({ number: 0.7, fromLow: 0, fromHigh: 1, toLow: 1, toHigh: 6 });
const rounded = bitbybit.math.roundToDecimals({ number: height, decimalPlaces: 1 });
const column = await bitbybit.occt.shapes.solid.createCylinder({ radius: 0.5, height: rounded, center: [0, 0, 0] });
await bitbybit.draw.drawAnyAsync({ entity: column });
Every function
| Function | What it does |
|---|---|
abs | Drops the sign of a number, so the result is never negative. |
acos | Finds the angle, in radians, whose cosine is the given number. |
add | Adds two numbers. |
asin | Finds the angle, in radians, whose sine is the given number. |
atan | Finds the angle, in radians, whose tangent is the given number. |
ceil | Rounds a number up to the whole number above it. |
clamp | Keeps a number within a range: below min becomes min, above max becomes max. |
cos | Finds the cosine of an angle given in radians. |
degToRad | Converts an angle from degrees to radians. |
divide | Divides the first number by the second. |
ease | Maps a value from 0 to 1 onto the range min to max along an easing curve, so the result speeds up or slows down instead of changing evenly. |
evalArithmetic | Works out a simple arithmetic expression written as text: numbers, +, -, the multiplication sign, /, parentheses and spaces. |
exp | Raises e, the base of the natural logarithm, to the power of a number. |
floor | Rounds a number down to the whole number below it. |
fract | Keeps the part of a number after the decimal point, measured up from the whole number below it, so the result is always from 0 up to 1. |
inverseLerp | Finds where a value sits between a start and an end, as a fraction: the t that lerp would need to produce it. |
lerp | Blends from a start value to an end value by a fraction t: 0 gives the start, 1 the end, 0.5 the midpoint. |
ln | Finds the natural logarithm of a number: the power e must be raised to for that number. |
log10 | Finds the base-10 logarithm of a number: the power 10 must be raised to for that number. |
modulus | Finds the remainder after dividing one number by another. |
moveTowards | Moves a value toward a target by at most maxDelta, without overshooting it. |
multiply | Multiplies two numbers. |
negate | Flips the sign of a number. |
number | Passes a number through unchanged, so a value can be given a name and reused. |
oneNrOperation | Applies one operation to a single number: absolute, negate, square root, rounding, logarithms, the trigonometric functions and their inverses, exponential, or a conversion between radians and degrees. |
pi | Gives the constant pi, the ratio of a circle's circumference to its diameter. |
pingPong | Bounces a value back and forth between 0 and length as t grows: up to length, back down to 0, and again. |
power | Raises the first number to the power of the second. |
radToDeg | Converts an angle from radians to degrees. |
random | Gives a random number from 0 up to, but not including, 1. |
randomNumber | Gives a random number between low and high. |
randomNumbers | Gives a list of random numbers between low and high. |
remap | Maps a number from one range onto another, keeping its relative position. |
round | Rounds a number to the nearest whole number; halves round up. |
roundAndRemoveTrailingZeros | Rounds a number to a given number of decimal places and drops the zeros at the end. |
roundToDecimals | Rounds a number to a given number of decimal places. |
sign | Tells the sign of a number: -1 when negative, 0 when zero, 1 when positive. |
sin | Finds the sine of an angle given in radians. |
smoothstep | Turns a value from 0 to 1 into a smooth S-curve that starts and ends gently; the value is clamped to that range first. |
sqrt | Finds the square root of a number. |
subtract | Subtracts the second number from the first. |
tan | Finds the tangent of an angle given in radians. |
tenPow | Raises 10 to the power of a number. |
toFixed | Formats a number as text with a fixed number of decimal places, keeping trailing zeros. |
twoNrOperation | Applies one arithmetic operation to two numbers: add, subtract, multiply, divide, power or modulus. |
wrap | Wraps a number into a range so it cycles round: past max it comes back in at min, and below min it comes back in at max. |



