4

I am trying to generate, say a non-linear sequence of 120 numbers in a range between 7 and 20.

I have already tried using numpy geomspace and logspace, which gave me pretty much the same outcome. It does what I want, but the resulted "curve" is not "sharp" enough so to speak.

import numpy as np
TILE_NONLINEAR = np.geomspace(7, 20, num=120)

I need to control an acceding and descending. A slow start and fast acceleration at the end and/or vice versa. Like for instance, outcome should be something like:

[7, 7.001, 7.003, 7.01 ..... 17.1, 17.3, 17.8, 18.7, 20]

or

[7, 7.8, 8.5, 9, ..... 19.9, 19.95, 19.98, 20]

The resulted sequences are off the top of my head just to give an idea.

Michael Butscher
  • 10,028
  • 4
  • 24
  • 25
EvolveX
  • 43
  • 3
  • Like an animation tweening curve. The rate of change is slower at the beginning and ending and faster in the middle. – Dan D. Jul 20 '19 at 21:34
  • lol, yeah. I am writing a routine inside Python API interface of the animation app. I'd be glad to use built-in curves, but unfortunately I need to write on every frame in this case. Thus generating sequence manually. – EvolveX Jul 20 '19 at 21:39

1 Answers1

2

There are bunch of nonlinear function that can be used for the task (some are listed here). Below is a simple exponential function to generate nonlinear array between two numbers. You can control curvature in the function:

import numpy as np

def nonlinspace(start, stop, num):
    linear = np.linspace(0, 1, num)
    my_curvature = 1
    curve = 1 - np.exp(-my_curvature*linear)
    curve = curve/np.max(curve)   #  normalize between 0 and 1
    curve  = curve*(stop - start-1) + start
    return curve

arr = nonlinspace(7, 21, 10)

#rounded result : [ 7., 9.16, 11.1, 12.83, 14.38, 15.77, 17.01, 18.12, 19.11, 20.]


Masoud
  • 1,270
  • 7
  • 12