On Functions

by Toby Grierson on 10/29/13 06:34:00 am

The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

Aspiring developers sometimes wonder *do I need to know math?* If you can think in terms of procedures, you can often get away with knowing little more than algebra and the boolean operators. Certainly you can cobble together a website. If you work in Unity 3D, many get away with just enough understanding of matrices, quaternions and vectors to nudge things around. No need for more, right?

But the moment you hit a *hard* problem, what? Give up? Or supplicate before Stack Exchange, gamedev.net, … Dear Prudence? Ouija Board?

Discrete mathematics is the star of computing what with sets, graphs (they come up a lot in “AI”) and more but let’s talk about functions. The ability to rejigger a function of your own; to solve for x; to factor it; etcetera. With a little imagination and a talent for story problems you can apply these techniques.

Let’s do an exercise. This here is a muffin:

This screenshot’s from the Turbo Slicer demo (my Unity asset I'm quite proud of); the sword is mouse controlled and the cursor drags it around to hack muffins. They’re flung onto the screen from a spawner below and gravity pulls them back down.

I tweaked the upward boost just right to fling them into the play area, but soon as I changed the gravity from -9.8 to some other figure, they would fly too high or low. And – long story short – this was not okay.

Wouldn’t it be magical if the code would just figure out the right speed? We know where we *want* the muffin. We know the gravity. So let’s do it.

First, we’ll create a function to yield the height of the muffin at a particular point in time.

Before I go on I’ll explain what this function means. Given the initial vertical speed *i*, the gravity acceleration *g* in the same unit of measure and the time *t*, we get the height *h*. For example, if the initial vertical speed is 5 (meters per second) and the gravity is 9.8 (meters per second square) than at 5 seconds in, the height is -97.5 meters.

Using *derivation* we’ll convert this from a function that gives us the *height* according to time into one that gives us the *vertical speed* according to time. Like so:

Given the same inputs as above (5, 9.8 and 5) we find that its speed is -44 meters per second. And why is that useful?

First it goes up, then down. The vertical speed must first be positive, then become negative when the gravity steers it downward. Therefore at the turning point – the peak – it will be 0. So if we assert that the vertical speed is 0 …

… and then solve for t …

… we get something magical. Given a specified initial speed and the gravity, this function yields the exact moment when the muffin reaches its peak. For our example numbers (5, 9.8) the answer is just a hair over 0.51 seconds.

If we *combine* that with the first function …

… we get a function with no time input. We can infer *t* from *i* and *g* and gain a function that tells us the maximum height *H* based only on the initial vertical speed and the gravity.

You see, we know the intended maximum height and we know the gravity and we want that initial speed so all we have to do is solve for *i*.

We place the intended maximum height and the gravity into the right hand side and out pops the intended height. Do we want to hit 5 meters up with a gravity of 9.8 meters per second squared? It needs to be flung up at a speed of 9.9 meters per second.

And I just retype it into C# …

private static float speedToReachDesiredHeight(float h)

{

float g = -Physics.gravity.y; *//Unity3D stores a vector like {0, -9.8, 0}*

float i = Mathf.Sqrt( ( h * g ) / ( 1f - g / (2 * g) ) );

return i;

}

… and now the code can be dropped into a project with different vertical gravity speeds and *just work*.

You may notice certain inputs give no sensible answer. Placing a 0 in for *g* gives a division by zero, or “undefined” result. This is fine; there is no single answer if the gravity is set to 0. I specifically did not let the two Gs in the lower fraction “cancel out” because that would change the function domain (the set of inputs for which it is valid).

The function’s behaviour is also not defined (in the “undefined behaviour” sense) for gravity that accelerates upward or for inputs where the requested altitude is toward the direction it’s going to fall; coping with these conditions are not in this function’s specifications. It’s simply an error to ask this question at all for some inputs.

Error handling is of course a project specific matter beyond the scope of this article.

In any case, it's an odd problem, but it's a real one. I hope this example gives some a better mental image of what all those story problems are for. Computers can offer far more difficult challenges when one wants to work on the frontiers of image processing, recognition, "AI" and others. Maths are the intellectual tools of the trade; they empower us to solve problems that can't yet be Googled. If you aim to work on the front lines, stay awake for math class.

–Toby