Jump to content

Formula to Calculate Exponential Curves?


 Share

Recommended Posts

Im messing around in HTML5 Canvas which uses Javascript to draw to the Canvas.  The Canvas is being used to display an RPG Character attribute over the number of levels.  Making a Linear Slope (straight line) is easy.

Im curious what the formula is to calculate the value for each level that implements an Exponential Curve?

 

The following image is from the Editor that I am trying to emulate.  This is a Non Exponential Curve, which I already have working.

XPflat.png

 

These are the Exponential Curves that I want to emulate, and I dont know the value of the Slider when its set to either "Fast" or "Slow", and "Middle" is a Non Exponential Curve (so guessing a value of 0 there.

XPfast.png

XPslow.png

What would I need to do to generate a curve that looks like this, where we input the Level 1 and Level 99 values?  Experimented with something like this but its not coming out anywhere like I need it to...

let exp_list = [null];
let pow = parseInt(slider.value);
for (let i = 1; i < 99; i++){
  exp_list[i] = 500 * (n ** pow) + 1; // ???? ab^x
}

Not quite sure what this formula is to plug in here.  Halp?

Link to comment
Share on other sites

There are an infinite number of ways to make a curve that hits (1,500) and (99,9999). Because there's a whole bunch of stuff that could happen in between those two points. This is expressed in your screenshot by the Fast/Middle/Slow slider.

The most obvious one would be the simplest:

x ** 0 + y = 500
-> y = 499

x ** 98 + y = 9999
-> x ** 98 + 499 = 9999
-> x ** 98 = 9500
-> 98 * ln x = ln 9500
-> 98 * ln x = 9.159
-> ln x = 0.09346
-> x = 1.0979663

1.0979663 ** (level - 1) + 499 = attribute

Note that it calculates based on level 1 being the baseline. That makes sense unless the characters actually start at level 0.

Link to comment
Share on other sites

Refresher math lesson:

The basic form of an exponential equation is a * (b ** n) + c. That's three constants (a, b, c) and one variable (n); you can throw more constants in there, like go overboard and use a * (b ** (c * n + d)) + e, but you probably won't need so many for this. It's exponential because some constant is raised to the power of some variable, and as the variable increases the result of the equation increases by much more.

You have two data points that you want an equation to cover: at level 1 the result should be 500 and at level 99 the result should be 9999. That means you have two equations to start with:

a * (b ** 1) + c = 500
a * (b ** 99) + c = 9999

When you have some number of equations and some number of things-to-solve-for, you can find a unique solution if the number of equations is >= the number of things. That's not the case here, which means there are going to be an infinite number of solutions.

One option is to eliminate a variable. I chose "a". So

b ** 1 + c = 500
b ** 99 + c = 9999

Two equations and two things so there's going to be a unique solution.

...but the math is a pain to find it. So I tweaked the equations a bit by taking the level and subtracting one.

b ** (1 - 1) + c = 500
b ** (99 - 1) + c =9999

The first equation loses one of the variables entirely (because anything ** 0 == 1) and so can be solved for the other (c=499), then that can get plugged into the other equation to solve it (b=1.0979663).
Fortunately tweaking the equations actually makes sense: at level 1 you should just be at the base stat so the exponential part shouldn't really be kicking in yet.

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

Took a break, but back at it...

    function calculateValues(){
      if (level1.value == '' || !level1.checkValidity()) return;
      if (level99.value == '' || !level99.checkValidity()) return;
      
      let rate = parseFloat(paramRate.value);
      let min = actor.parameters[selectedParameterId][0], max = actor.parameters[selectedParameterId][98];
      if (isNaN(min) || isNaN(max)) return;
      
      let n = (max - min) / 98;
      
      for (let i = 0; i < 99; i++){
        // This is wrong, it only calculates linear increase, not Exponential
        actor.parameters[selectedParameterId][i] = min + Math.round(i * n);
      }
    }

My biggest problem is that my final value needs to be what ever the user has in the "Level 99" box...

Link to comment
Share on other sites

Would that not be the level99.value you're already using at the beginning of the function?

For your other question, I don't know the right way of going about the math to find a function that lets you scale from a gradual increase (ie, a line) to a severe curve (like the one generated by the formula I gave earlier). To solve that I suggest seeing what you can find on the internet - anything ranging from straight math to some sort of try-it-out graphing tool; the basic form of the final equation will probably be along the lines of a*e^n + b*n + c.

Link to comment
Share on other sites

On 6/22/2022 at 4:25 AM, requinix said:

Would that not be the level99.value you're already using at the beginning of the function?

For your other question, I don't know the right way of going about the math to find a function that lets you scale from a gradual increase (ie, a line) to a severe curve (like the one generated by the formula I gave earlier). To solve that I suggest seeing what you can find on the internet - anything ranging from straight math to some sort of try-it-out graphing tool; the basic form of the final equation will probably be along the lines of a*e^n + b*n + c.

I believe you are correct, and I think it results from level99.value ** 1.  I think...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.