Learn how to implement some more advanced math functions, with some help from the C++ standard library.

Posted

In the previous lesson, we talked about exponents and square roots. Lets see how we can implement them inÂ C++

We saw how we could do something like $2^3$ is equal to $2 \times 2 \times 2$, or $8$. This is sometimes also *called raising 2 to the 3rd power*.

We'd like to be able to do this in code. One way we might be to have a function we can call with two numbers - a *base* and a *power*. For example, $2^3$ might comeÂ from:

`pow(2, 3);`

Or, more generally, we'd have two variables like $x$ and $y$, and we could calculate $x^y$ byÂ doing:

`pow(x, y);`

We perhaps know how we could create such a function - that function might involve a loop that multiplies `x`

by `x`

until some condition involving `y`

is no longer true. Fortunately, the standard library has already implemented this, and many more maths helpers forÂ us.

`CMath`

To access the standard libraries math utilities, we need to include `<cmath>`

:

`#include <cmath>`

In some compilers, the `#include <cmath>`

declaration will throw an error. It may be necessary to use `include <math.h>`

Â instead

After including `cmath`

or `math.h`

the `pow`

function is now available within the `std`

Â namespace:

`std::pow(x, y);`

Like with any namespace, if we have an appropriate `using`

statement, we can omit the scopeÂ resolution:

```
using namespace std;
pow(x, y);
```

When we need to raise something to a small power, we don't need a helper function. For example, to raise `a`

to the power of `2`

, it's likely easier to have our code be `a * a`

rather than `pow(a, 2)`

Implementing a function that calculates the square root ourselves would be a bit more difficult, with what we've learnt soÂ far.

Fortunately, `CMath`

gives us access to the `std::sqrt`

functionÂ too:

```
#include <cmath>
std::sqrt(25); // 5
```

What if we wanted to get the square root of `-25`

?

There's no real number that can multiply by itself to give an answer of `-25`

, or any other negativeÂ number.

Because of this, when we're using square root functions, we typically want to make sure that the thing we're trying to calculate the square root of isÂ positive.

If our program ever finds itself needing to get the square root of a negative number, it's likely we made a mistake in our logicÂ somewhere.

If we do end up passing a negative number to `std::sqrt`

, this will result in an exception being thrown, which may get our program into a brokenÂ state.

Programming a computer to calculate the square root of an input variable is not as easy as it seems. There are many different algorithms that can be used, each with their advantages andÂ disadvantages.

The standard library's `sqrt`

function has the advantage of being extremely accurate, but quite slow. This is often not the trade off we want when working with graphics, particularly when we may be doing thousands of these calculations perÂ frame.

Typically, we prefer a faster implementation that gets an approximateÂ answer.

Because of this, `std::sqrt`

tends to not be used in these type of applications. But, for simplicity, we'll stick with it in thisÂ course.

With these new functions at our disposal, we can now update our `Vector3`

struct with the ability to return its length, as well as the distance to anotherÂ vector.

```
#include <cmath>
struct Vector3 {
float x;
float y;
float z;
float GetLength() {
return std::sqrt(x * x + y * y + z * z);
}
float GetDistance(const Vector3& Other) {
using namespace std;
return sqrt(
pow(x - Other.x, 2) +
pow(y - Other.y, 2) +
pow(z - Other.z, 2)
);
}
};
```

With these new additions to our toolbox, we are now able to introduce the concept of attack range to ourÂ characters.

For example, by comparing the `WorldPosition`

of our character to the `WorldPosition`

of its target using the `GetDistance`

function, we can see how far away the two objectsÂ are.

This would allow us to prevent our character from attacking an enemy that is too far away. We could also implement behaviours like character doing more damage to targets in meleeÂ range.

In the next lesson, we will take this further, and introduce some additional vector math. This will allow us to implement rules around how characters can change their `WorldPosition`

, giving us the groundwork for character movement. See youÂ there!

Was this lesson useful?

Posted

This lesson is part of theÂ course:### Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games