1
$\begingroup$

I'm programming a game and am looking to create a non-linear relationship between input and output, such that as the input increases, the output increases, but the higher the input value, the corresponding output increment is less and less.

I've looked at logarithms, and that seems to be the effect I'm looking at.

o = log(i), where o is the output value and i is the input value.

But this is too extreme - the curve is too steep. If I try to modify this with

o = log(i)k, where k is some constant multiplier, creates too steep of a curve in the lower end.

I'd like to find a way to make the falloff more gradual. Unfortunately, I can't seem to find any other functions in my programming language (ActionScript 3) that will do the trick.

Where should I be looking? Are there any functions I should be trying to replicate?

Thanks in advance - I realize this is a pure maths forum, but it seemed like the best place to ask.

  • 0
    What's the domain for your inputs, and what do you want the curve to look like at the lower end? It seems like you could simply move the logarithm to the left appropriately and that would resolve your problems...2011-08-04
  • 0
    the inputs would be positive real numbers. The curve should be fairly linear in the lower end. I'd like to then be able to "play" with the factor to tweak the slope of the curve. How do you "move the logarithm to the left?" log(i-n)?2011-08-04
  • 1
    You're close: $\log(\mathrm{input}+x)$, for some translation distance $x$. Try it out for yourself. (Have you heard of Wolfram|Alpha yet?)2011-08-04
  • 0
    If $\log i$ ultimately grows too slowly for you, you can try $i^k$ for some $k$ between $0$ and $1$, like $k=1/2$, or $1/3$. There is still the steepness problem, which can be fixed for example with $(1+i)^{1/3}-1$, which is in the spirit of what @anon suggested. You will need to fool around, tweak parameters until things look good.2011-08-04
  • 0
    @anon, wow Wolfram|Alpha is pretty sweet. So this formula gets me reasonable close: (log(n+30)-log(30))70 with the problem that the slope doesn't fall off to 0 at the outer end. That would be ideal. Note that I found that when you add to n, you have to subtract the log of that same amount in order to keep the line above 02011-08-04
  • 0
    @Andre, thanks for this alternative. I can't seem to correlate x and y in (x + i)^k - y to a) get the slope to approach 0 (admittedly, this was not a requirement I stated in my original post) or b) tweak the slope and still maintain an output value of 0 when i = 0. In other words I'm having difficulty using those two values to control the starting and ending points of my curve. I'm not sure I'm expressing myself very well here.2011-08-04
  • 0
    The slope of say $(1+i)^{1/2}-1$ does approach $0$ as $i$ gets large. But maybe not fast enough for you. What about $1-2^{-i}$, for $i \ge 0$? Slope approaches $0$ very fast, and we are linear near $0$. To make the effect less extreme, divide $i$ by $3$ or $4$.2011-08-04

2 Answers 2

1

I would suggest trying a function of the form f(X)=A*(1-exp(-B*x))+C.

This functional form gives you pretty good control over the appearance of the curve since it starts with f(0)=C and converges to f(inf)=A with the rate of convergence given by B.

  • 0
    Thanks, this looks promising, though I can only make it work reliably for B = .012011-08-04
  • 0
    (ran out of edit time!) I'm having trouble figuring out how A and B relate, if I'm looking to "cap" the slope to 0 at X=n. For example, say I'm plotting this from 0 to 400 and want to see the slope at 0 when X=400. Is there some logic to A and B that I can apply? In my tests, for example, 400(1-exp(-.005*x)) flattens out around x = 1000. What if I wanted it to flatten out at 400 - am I just playing around with A and B until my plot empirically seems to achieve that?2011-08-04
  • 0
    @Tom Augur: If you want to cap the slope at X=n, just do if X>n: X=n. Then apply your function to X.2011-08-04
  • 0
    @Ross Millikan, unfortunately that would then truncate the curve - making a "hard stop" rather than a smooth decay.2011-08-04
  • 0
    @Tom Auger, Basically you have to just play with parameters until it fits what you want it to do. If you can't get it to work then you have to increase the complexity of the function. This function had a slope that is given by f'(x)=A*B*exp(-B*x), this means it goes to zero as B*x gets large, this means for smaller B the function will converge slower.2011-08-05
  • 0
    @Tom Auger, Thinking about it a little bit more I think you should try f(x)=A*(1-exp(-B*x^n))+C, this should give you a finer control over the convergence of the function.2011-08-05
0

I'm by far not the smartest guy in math, admittedly, but through brute trial-and-error, this function seems to achieve what I need:

for a factor f - if greater than 1.0, you'll have a "flattening" of the curve (gamma) and if between 0.0 and 1.0, you'll get a "bumping" of the curve

for a range from 0 - max

x^f / max^f * max

Example on Wolfram Alpha here