Map range function


#1

I was going to suggest adding a range method to FastMath, but it appears that there is already a method.

FastMath.interpolateLinear(FastMath.nextRandomFloat(), 5, 12);

Is there one I’m missing that maps one range to another - a.k.a this?

// maps one range to another.
// e.g. I have one range at 2-12 and I want it in the range 0-FastMath.PI.
private float map(float value, float oldMin, float oldMax, float newMin, float newMax) {
    return (((value - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin;
}


#2

I am not a math guy, but yep I think maybe good to include it.
I remember once I also needed this mapping functionality, but I couldn’t find it FastMath.
I just found one that was doing a normalizing:


#3

Which means it’s a normalize and a lerp, right?

Edit: wow… that normalize() method seems really bad… ah, it’s only useful for angles and will be silly for anything else. Badly named.

…and that’s the problem with the map range method. To me it’s hard to come up with a name because it’s really two separate operations.


#4

What about rangeLerp?

Edit:
or
interpolateLinearRanged()

or just the same interpolateLinear name with five arguments with a proper java doc explanation.


#5

So something like…?

    /**
     * Converts one range into another.
     * Interpolates between newMin and newMax with the given value between oldMin and oldMax.
     * @param value  the value between oldMin and oldMax.
     * @param oldMin the minimum old value.
     * @param oldMax the maximum old value.
     * @param newMin the minimum new value.
     * @param newMax the maximum new value.
     * @return
     */
    private float interpolateLinear(float value, float oldMin, float oldMax, float newMin, float newMax) {
        return (((value - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin;
    }

#6

Yep.


#7

But it’s not just an interpolation. It’s uninterpolating one range and reinterpolating another.

There has to be a name for that uninterpolating but it escapes me at the moment.

Edit: at best combining the tyoe is a reinterpolation()… though I’m still convince passing 5 arguments to a math function is a bad sign.


#8

Reinterpolate sounds like a better description.

In p5.js they do the same as me except worded better. I guess I could use a couple vec2’s or a vec4 as the ranges? I’m not sure how I could lessen it other than that unless something obvious is escaping me.


#9

It’s not about the raw argument count… and you certainly don’t want to be creating totally-completely-100% unrelated objects just to avoid a raw argument count.

To me, it just seems that glomming on a bunch of arguments to a “simple math” function is a sign that it’s not a “simple math” function… but more than one.
lerp(unlerp(x, min, max), newMin, newMax)

The fact that we can’t come up with a good name for it is also a sign that it’s overloaded… but so far to me “reinterpolate” is the best name.

The problem with “map” is that it means 100 other things directly related to games and software development that are not even reasonably close to the meaning of this function.


#10

Oh I see. You’re right. We have an interpolate as mentioned in the OP. And in fact there is also an extrapolate method. The word that escaped you.

So really it’s not even necessary. It turns two lines into one. That FastMath class is full of surprises.

https://javadoc.jmonkeyengine.org/com/jme3/math/FastMath.html#extrapolateLinear-float-float-float-


#11

Extrpolation is something different. It’s like an interpolate that is not bound by the range… it can extend beyond for values outside of 0-1.


#12

Ugh. Ok. It’s like 10pm here. I’ll write an uninterpolate method tomorrow and that should solve the concern you had, which I agree is not right.


#13

To me that looks like a 1D transformation from one “range”-coordinate-system to another. It’s just scaling and offsetting, no?


#14

So here’s the missing method.

    /**
     * Converts a range of min/max to a 0-1 range.
     * @param value the value between min-max (inclusive).
     * @param min   the minimum of the range.
     * @param max   the maximum of the range.
     * @return A value between 0-1 if the given value is between min/max.
     */
    public static float unInterpolateLinear(float value, float min, float max) {
        return (value - min) / (max - min);
    }

#15

Thanks :slightly_smiling_face:


#16

I vote for
mapTo01
mapToRange

unInterpolateLinear is the opposite of descriptive in my opinion.


#17

Except that it’s unmapping the range.

Naming is hard. There has to be a mathematical term for ‘uninterpolating’.


#18

Its usually just called unlerp from what I’ve seen. In the jme lib it’s written longhand - interpolateLinear - instead of lerp -, so I just went with that. I don’t mind what it’s called, but I understand completely that it’s important if it’s going to be there forever.


#19

Personally, I’m ok with this name unless some math-guy pipes up with a proper name for it.

unlerp, uninterpolate… entirely clear to me what that means.


#20

PR Submitted. I’ll just merge it when the checks are complete. PR link submitted here for clarity of process/outcome.