qr code

BIT-101

Bill Gates touched my MacBook Pro

FOTD: Norm


[ fotd ]

I’m going to do a series of short articles, labeled FOTD - Function Of The Day. These might be math functions, drawing functions, PRNG functions, color functions, etc. Mostly these will be useful for visual or creative coders.

Each post will be short. Just a single function, how it works, what it might be used for, and maybe an example or two. No particular schedule for these. As the mood strikes me. But between the two main libraries I’ve curated, blcairo and bitlib, I have close to 1000 functions, so there should be no shortage of material. Maybe worth noting that I’ll usually be using some kind of pseudocode for all the examples.

Norm

Today’s function is norm. This takes in three parameters: value, min and max. It returns a number between 0.0 and 1.0 based on where value falls between min and max. Actually, if value is less than min it will return a negative number, and if value is greater than max it will return something larger than 1.0. But in most use cases, the min/max range will be contrived so that value fits into it cleanly.

The Code

In pseudocode, norm looks like this:

function norm(value, min, max) {
	return (value - min) / (max - min)
}

The max - min part gets the range between those two values. Subtracting min from value puts value into that range (if it can be put into that range). Dividing the two give you zero if value equals min, one if value equals max and somewhere between if value is between the two.

Example(s)

There’s one use for norm that’s immediately useful. I often use Perlin or Simplex noise to generate patterns or what have you. In some libraries these noise functions return a value between 0.0 and 1.0, which is already normalized. But in most, they return a value from -1.0 to 1.0. I have color functions that take values for channels in floats between 0.0 and 1.0, so I need to convert between the two.

I could say:

colorValue = (noise + 1) / 2

// or...

colorValue = noise / 2 + 0.5

Adding one moves the noise range to 0.0 to 2.0. Dividing by two puts it into a normalized range. The second version does something similar.

With norm I can say:

colorValue = norm(noise, -1, 1)

It’s a couple more characters, but for me, less of a cognitive load. There’s no math involved, I’m just mapping from -1, 1 to 0, 1.

Norm is often used as just one step in a calculation. Once you have the norm, you might want to do some further calculations with that value.

Say I was using atan2 to calculate angles between two points, like a center point and another pointer. This gives you a number from -PI to PI. You can use norm to normalize that to a 0, 1 range. Multiply that value by the width of the canvas, in my case 400, and now you can use that to draw a kind of gauge showing the value. Like so:

angle = atan2(y - centerY, x - centerX)
value = norm(angle, -PI, PI) * 400
moveto(value, 0)
lineto(value, 20)

Now this might seem a little bit contrived, because honestly it is. The fact is, I don’t use norm by its own all the much other than the noise example above. But it goes well inside other more complex functions, some of which we’ll visit later.

Resources

I did a video on this function on my Coding Math Youtube channel. View it here: Coding Math Mini #1, Normalization

Photo by Markus Spiske

« Previous Post
Next Post »

Comments? Best way to shout at me is on Mastodon

Or share this post directly on Mastodon