Oh… Yeah… Maths, so hated and useful at the same time… Many people are afraid of this when they start programming, because they think they are not capable, that they will not understand it or they are simply lazy to learn, but it is not as difficult as most people think, with this post, I will try:

# Math library

### Values

## math.pi

Returns the number pi (𝛑).

## math.huge

Returns infinite.

### Approaches

## math.floor(x)

This function removes the decimals from a number and leaves only the integer part.

```
math.floor(5.9746) --> 5
math.floor(543.235) --> 543
```

## math.ceil(x)

This function checks if the number you give it has decimals, if so, it returns the next number, if not, it stays as is.

```
math.ceil(6) --> 6
math.ceil(6.1) --> 7
math.ceil(6.5) --> 7
math.ceil(6.9) --> 7
```

## math.round(x)

This function rounds the number, looks at the first decimal place and if it is five or more, it gives the next number, if it is less, it removes the decimals.

```
math.round(5.5) --> 6
math.round(5.3) --> 5
math.round(5.8) --> 6
```

### Random numbers

## math.random(min, max)

This function gives a random number between the first and the second, if you only give a number, it will give you a random number between 0 and the number you have specified, but if you do not put any number, it returns a random number between 0 and 1.

```
math.random(5, 10) --> Any number between 5 and 10
math.random(10) --> Any number between 0 and 10
math.random() --> Any number between 0 and 1
```

## math.randomseed(x)

Random numbers do not really exist, so we use a substitute, **pseudo-random numbers**. I’m sure you’re wondering how Roblox does it with math.random or any other game, it’s easy, there’s a trick to it.

First you have a formula, for example, `7*seed+3`

, where seed is any initial number, in this case we will use 2, then the calculation `7*2+3=17`

is done, then the 17 is set as seed being the next calculation `7*17+3`

and so on, but of course we also have to go back and not just increase, then we put a maximum and see how many times the result of that number passed, so if it is 5, 15 would be removed from the 17, leaving 2 and so on.

So, knowing this, this function establishes the seed of the pseudo-random numbers:

```
while task.wait(.5) do
math.randomseed(1)
print(math.random(10))
end
```

If you put this code, you will see that, despite being a random number, it is putting the same number, since you are specifying a seed before each math.random, converting it all the time in the same calculations, therefore, same result.

### Minimum and maximum

## math.min(x, y, ...)

This function accepts any number of numbers to compare them and return only which is the smallest.

```
math.min(7, 5, 45, 2, 78) --> 2
math.min(567, 464, 251, 875, 753) --> 251
```

## math.max(x, y, ...)

This function accepts any number of numbers to compare them and return only which is the largest.

```
math.max(7, 5, 45, 2, 78) --> 78
math.max(567, 464, 251, 875, 753) --> 875
```

### Cut out numbers

## math.sign(x)

If the number is less than 0, returns -1, if greater, returns 1, and if 0, returns 0.

```
math.sign(.3) --> 1
math.sign(0) --> 0
math.sign(-.3) --> -1
```

## math.clamp(x, min, max)

This function requires three numbers to be specified, the number, the minimum and maximum. If the number is less than the minimum, it returns the minimum; if it is greater than the maximum, it returns the maximum and if it is between those two numbers, it does not modify it:

```
math.clamp(5, 3, 7) --> 5
math.clamp(5, 7, 10) --> 7
math.clamp(5, 4, 0) --> 4
```

### Easy calculations

## math.abs(x)

Returns the absolute value of the number (i.e. the number in positive).

```
math.abs(5) --> 5
math.abs(-5) --> 5
```

## math.pow(x, y)

Returns x raised to y (x^y).

```
math.pow(5, 2) --> 5^2 --> 25
```

## math.sqrt(x)

Returns the square root of the specified number.

```
math.sqrt(25) --> 5
```

## math.exp(x)

Returns e^x (e is the Euler’s number, exponential of x).

```
math.exp(5) --> 148.41315910258
```

## math.fmod(x, y)

Returns the remainder of the division of x/y (can also be calculated with x%y)

```
math.fmod(10, 3) --> 1 (10%3)
math.fmod(10, 2) --> 0 (10%2)
```

### Logarithms

## math.log(x, y)

A logarithm is an infinite curve that never becomes straight, useful for calculating the experience needed to level up.

This function needs a number and a base (the base defines what the curve looks like) and returns the result of the logarithm of base y of x:

```
math.log(10, 5) --> 1.4306765580734
math.log(10, 10) --> 1
math.log(10, 3) --> 2.0959032742894
```

## math.log10(x)

This function returns the base 10 logarithm of x (it is like putting math.log(x, 10)).

```
math.log10(10) --> 1 (math.log(10, 10))
```

### Angles

## math.rad(x)

A radian is a measure of angle, somewhat like degrees, with the difference that 90º is 𝛑/2 rads, 180º is 𝛑 rads, 270º is 3𝛑/2 rads and 360º is 2𝛑 rads. This is used for rotations with CFrame.

What this function does is to pass an angle in degrees and return it in radians.

```
math.rad(180) --> 𝛑 (3.1415926535898)
```

## math.deg(x)

This function converts radians to degrees.

```
math.deg(math.rad(180)) --> 180
math.deg(2𝛑) --> 360
```

### Trigonometry

## math.sin(x)

The sine is a trigonometric function which represents the Y position of a series of points that form a circle of radius 1, so it sounds a little complicated, but let’s take a closer look:

This one here is its graph, if you look at the number line below, it is in radians since both the sine, cosine and tangent we will need to give it an angle in radians.

As we can see, the sine, depending on the angle you give it, gives values between 1 and -1.

As you know, a right triangle can be drawn between two points, because the sine of an angle is the size of the opposite leg between the inside of the circle and the corresponding point on the circle according to the angle:

## math.cos(x)

The cosine is the same as the sine but changing the axis, but first, let’s see its graph:

As can be seen, it is quite similar to the breast with the difference that it is slightly moved horizontally.

This, like the sine, represents a leg of the right triangle at the center of the circle and a point on the circle that corresponds to the angle that is given to the cosine, but instead of being the opposite, it calculates the adyascent:

## The magic of joining sine with cosine

If we put these two functions (sine and cosine) together we can calculate a position on the circle, which we can use to make orbits or calculate directions from an angle. Using this method is simple and easy to attach because, as it goes from -1 to 1, we can not only multiply the position obtained to enlarge the radius of this circle, but also just by adding we can change the center position of the circle:

## math.tan(x)

The tangent is the division between sine and cosine.

It represents the distance from the point it intersects on a tangent line to a point on the horizontal dividing line:

But this presents us with a problem, in spite of infinite elongation, if we are at 90º or 180º, the line with the hypotenuse is perfectly parallel with the tangent line, then it will go out to infinity.

Its graph would look like this:

## math.asin(x)

This function is said to be the inverse of the sine function since, instead of obtaining a Y position on the unit circle from an angle, it returns an angle from that Y position. (asin(sin(x)) = x)

## math.acos(x)

This function is said to be the inverse of the cosine function since, instead of obtaining a position X on the unit circle from an angle, it returns an angle from that position in X. (acos(cos(x)) = x)

## math.atan(x)

This function is said to be the inverse of the tangent function since, instead of getting a distance, you get an angle from that distance. (atan(tan(x)) = x)

## math.atan2(y, x)

Imagine a right triangle drawn from two points:

If you notice that the hypotenuse is a segment that connects both points, this tells us that we can obtain the rotation that we must apply to one point to make it look at the other. This is exactly what this function is for! But… we have to pass two numbers, the height and length of the triangle, to obtain it, we simply subtract the positions.

But… Watch out! The result is given in radians, keep that in mind when using it.

## math.sinh(x)

This is exactly the same as the sine, but with the difference of being on a circle, it is on a hyperbola:

## math.cosh(x)

This is exactly the same as cosine, but with the difference that it is on a circle, it is on a hyperbola:

## math.tanh(x)

This is exactly the same as the tangent, but with the difference that it is on a circle, it is on a hyperbola:

### Extras

## math.noise(x, y, z)

Perlin Noise is a black and white image that has the peculiarity of having white dots on a black background surrounded by gray areas:

For this function you must put three numbers of which two are optional (if you do not put them, they will be set as 0) which are coordinates to know which point of the image to look at and give a value between 0 and 1 depending on the color it is.

This can be used for a map generation.

## math.modf(x)

This function returns the integer and decimal part of the number separately:

```
math.modf(3.5) --> 3, 0.5
```

## math.ldexp(x, y)

This function makes the formula for you: x * 2 ^ y

## math.frexp(x)

This function returns the unknown m and n considering that: x = m*2^n

# Some formulas

## Quadratic trajectory

Sometimes we need to calculate the position in the plane of a thrown object, such as an arrow, a stone or a bird.

Formula: `origin + direction * t + (gravity*t*t)/2`

First let’s put this formula into a function and specify everything the formula needs to calculate the position:

```
local function getPosition(origin, direction, gravity, t)
return origin + direction * t + (gravity*t*t) * .5
end
```

Let’s start by specifying the origin, this must be a vector which is the position from where the object is launched.

```
local origin = workspace:WaitForChild("Origin").Position
```

The direction must also be a vector that, as the name says, tells where to launch, for this you can use trigonometry or LookVector, RightVector and UpVector.

```
local direction = workspace:WaitForChild("Origin").CFrame.LookVector * 50 + workspace:WaitForChild("Origin").CFrame.UpVector * 67
```

Gravity is also a vector that of magnitude is the force of gravity and of course, it has to go downward:

```
local gravity = Vector3.new(0, -workspace.Gravity, 0)
```

Finally we need t (time) which tells the point of the trajectory where we are, to obtain it, what we will do is to specify an initial value (0) and constantly we will add deltaTime (time between frame and frame in one second) and if you want to modify the speed just multiply it by a number:

```
local t = 0
while true do
t += game:GetService("RunService").Heartbeat:Wait()
end
```

And it would be just a matter of applying the formula!

```
local function getPosition(origin, direction, gravity, t)
return origin + direction * t + (gravity*t*t) * .5
end
local gravity = Vector3.new(0, -workspace.Gravity, 0)
local originPart = workspace:WaitForChild("Origin")
local origin = originPart.Position
local direction = originPart.CFrame.LookVector * 50 + originPart.CFrame.UpVector * 67
local bullet = workspace:WaitForChild("Bullet")
local t = 0
while true do
bullet.Position = getPosition(origin, direction, gravity, t)
t += game:GetService("RunService").Heartbeat:Wait() * .5
end
```

Here you can download a place with the system already made to test it!

Baseplate.rbxl (32.0 KB)

## Converting from Euler to Quaternions

Quickly explained, a quaternion is a four-axis rotation based on complex numbers, which is a calculation of a number with an imaginary number (imaginary numbers are non-existent numbers, such as the square root of -1).

Thinking about quaternions is difficult, but there is a formula that makes it easy to create them:

**W = cos(x/2) * cos(y/2) * cos(z/2) - sin(x/2) * sin(y/2) * sin(z/2)**

**X = cos(y/2) * cos(z/2) * sin(z/2) + cos(x/2) * sin(y/2) * sin(z/2)**

**Y = cos(x/2) * cos(z/2) * sin(y/2) - cos(y/2) * sin(x/2) * sin(z/2)**

**Z = cos(z/2) * sin(x/2) * sin(y/2) + cos(x/2) * cos(y/2) * sin(z/2)**

```
local function Axis2QuaAxis(x, y, z)
x *= .5; y *= .5; z *= .5;
local ca, sa = math.cos(x), math.sin(x)
local cb, sb = math.cos(y), math.sin(y)
local cc, sc = math.cos(z), math.sin(z)
local Axis = {
w = ca * cb * cc - sa * sb * sc;
x = cb * cc * sa + ca * sb * sc;
y = ca * cc * sb - cb * sa * sc;
z = cc * sa * sb + ca * cb * sc;
};
return Axis
end
```

To convert this to quaternions, this is done with CFrame.new(x, y, z, qX, qY, qZ, qW).

# Number

## Scientific notation

Scientific notation is used to abbreviate a number that has too many zeros, such as 1,000,000. This is normally done by raising 10 to the number of zeros but in Roblox you can put it directly.

We must see where the zeros are, that is, if it is 0.000001 or 1,000,000 (if they are in front or behind the point), if it is in front we will use the + symbol and if it is behind the - symbol. Once we know the symbol we only have to put 1e symbol number of zeros, for example:

```
1e+5 --> 100000
1e-5 --> 0.00001
```

## Hexadecimal

We count in decimal (base 10), if so called because we have ten numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. When we reach 9, we add one to the previous number and start again, 9 ->+10, 11, 12, 13, 14, 15, 16, 17, 18, 19… Counting in hexadecimal is exactly the same, but with the difference of counting with more numbers, which, to avoid creating more symbols, we use letters: 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. Here it is the same, when we reach f we add one to the next number: f → +10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 19, 1a, 1b, 1c, 1d, 1e, 1f… It is possible to count like this in roblox but we must put 0x in front:

```
0xa --> 10
0x10 --> 16
0xc4df0a --> 12902154
```