[HN Gopher] I'm Unsatisfied with Easing Functions
       ___________________________________________________________________
        
       I'm Unsatisfied with Easing Functions
        
       Author : ndyg
       Score  : 27 points
       Date   : 2025-07-16 17:30 UTC (7 days ago)
        
 (HTM) web link (www.davepagurek.com)
 (TXT) w3m dump (www.davepagurek.com)
        
       | ndyg wrote:
       | The friction Dave describes where changing one param effects all
       | the other params in an animation brought to mind this section of
       | an old Bret Victor talk:
       | https://www.youtube.com/watch?v=a-OyoVcbwWE&t=716s
        
       | unconed wrote:
       | Bouncy animations that overshoot just seem like a bad idea in
       | general. The purpose of a UI animation is to guide the eye, but
       | the bounce explicitly introduces a reversal of motion at the end
       | before stopping.
       | 
       | Easing functions are just very cargo culty. We've had the same
       | basic set that dates from the Flash era. Now there's an Apple
       | variant that's just a parametric version of the same idea, but it
       | lacks guaranteed continuity and it's even harder to control?
       | 
       | Personally I've had far better results using the repeated-
       | lerping-towards-a-target trick, aka a true exponential ease. When
       | stacked, you get a classic LTI (linear time invariant) system,
       | and the math around how those behave is well established.
       | 
       | Classic hand-drawn animation does often use stretching and
       | squeezing to emphasize and to create a sense of anticipation, but
       | that's very different and always dependent on the specific
       | motion. You can't automate that by making everything act like
       | jello.
        
         | pahgawk wrote:
         | Hi, author here! When writing this, I was thinking more in the
         | space of procedural character animation and motion graphics
         | than UI animations. That's part of why I want a system with
         | nice parameters, so that I do have the ability to fine tune and
         | tweak the motion to fit the context. My background is in
         | classical animation so it's something I might just keyframe by
         | hand in a non-code context, or in Flash when it's easier to
         | jump back and forth between code and non code. Although I think
         | having it parameterized still can lead to interesting
         | opportunities for variation in procedural animation!
        
         | ipv6ipv4 wrote:
         | Overshoot is important for scroll views. Without the bounce,
         | there is no feedback if you have scrolled to the edge or not.
         | Early Android lacked the bounce, and it would invariably lead
         | to users scrolling again to be sure they had indeed scrolled to
         | the edge of the view.
        
           | Jyaif wrote:
           | > Early Android lacked the bounce
           | 
           | Early android had some visual feedback (a gradient that faded
           | out) instead of the bounce, possibly because Apple owns a
           | patent ( https://patents.google.com/patent/US7469381B2/en ).
           | 
           | Current Android still does not use the bounce, and instead
           | stretches the content, which works well enough on the high
           | resolution screens that we have now.
        
       | Trung0246 wrote:
       | There was an old experiment of mine where I tried to mix match
       | easing function, maybe it'll be of interest to you
       | 
       | https://codepen.io/Trung0246/pen/jxvvzY
        
       | EsportToys wrote:
       | Closed-form (non-iterative) PID solution:
       | 
       | https://www.desmos.com/calculator/mu80ttc9aa
       | function sprung_response(t,pos,vel,k,c,m)           local decay =
       | c/2/m           local omega = math.sqrt(k/m)           local
       | resid = decay*decay-omega*omega           local scale =
       | math.sqrt(math.abs(resid))           local T1,T0 = t , 1
       | if resid<0 then              T1,T0 = math.sin( scale*t)/scale ,
       | math.cos( scale*t)           elseif resid>0 then
       | T1,T0 = math.sinh(scale*t)/scale , math.cosh(scale*t)
       | end           local dissipation = math.exp(-decay*t)
       | local evolved_pos = dissipation*( pos*(T0+T1*decay) + vel*(   T1
       | ) )           local evolved_vel = dissipation*( pos*(-T1*omega^2)
       | + vel*(T0-T1*decay) )          return evolved_pos , evolved_vel
       | end
       | 
       | For anticipation, just add an extra initial velocity in the
       | opposite direction and let the closed-form solution handle the
       | time evolution. The main trick here is to keep both position and
       | velocity as state. There is no need to "step through the
       | simulation".
        
         | thomascountz wrote:
         | Wow, this is great!
        
         | joenot443 wrote:
         | Wow, this is excellent!
         | 
         | Is there a name for this kind of motion? I'd love to use it
         | sometime.
        
           | EsportToys wrote:
           | It's the general solution to a damped harmonic
           | oscillator/mass-spring-damper system:                   m *
           | x'' + c * x' + k * x = f(t)
           | 
           | See https://web.archive.org/web/20230604215211/https://esport
           | toy...
        
         | pahgawk wrote:
         | This is good! Although I'd also say that initial velocity
         | doesn't _quite_ cover what I was talking about in the post --
         | even anticipation arguably can start from 0 velocity,
         | accelerate backwards, decelerate, then accelerate in the
         | opposite direction. Imo, any sudden change in velocity should
         | by default be avoided (there are always valid uses where
         | breaking that expectation is good, but I 'd want it smooth by
         | default.)
         | 
         | That could possibly be done by incrementally changing force to
         | move it back first, then forward, or to model this as a PD
         | controller following an input with some baked in reversal
         | before moving forward. That can still be closed-form (state
         | response to a known input will be; Laplace transforms can help
         | there), but still would need a bit of effort to model and tune
         | to look right.
        
           | LegionMammal978 wrote:
           | You wouldn't really need an incremental force: a step-
           | function force (first backward for some time steps, then
           | instantly forward) will still produce a continuous velocity
           | curve.
        
             | pahgawk wrote:
             | true! I suppose you'd risk getting some oscillations in the
             | anticipation depending on the scale of the force, but that
             | could be desirable, or might not happen if the scale is
             | small enough, and certainly makes the math a little easier
        
               | EsportToys wrote:
               | You can trivially calculate the time-to-peak overshoot
               | using the closed form equation. It's the first
               | (0-indexed) zero of the velocity response, i.e. happens
               | at t = (pi / scale)
               | 
               | And obviously it would only apply for the underdamped
               | case.
        
       | f33d5173 wrote:
       | To me this article is ridiculous bcause the first thing I think
       | of when I hear "easing function" is the css version of that
       | concept, which seems to solve all the authors problems? The css
       | easing functions are weirdly limited, because they consist of a
       | single function that takes 4 parameters, then a bunch of
       | specializations of that function. There are great websites on the
       | internet for configuring those parametere though, and they are
       | quite general from a practical standpoint. It should be trivial
       | to emulate the concept in any other language/system.
        
         | shermantanktop wrote:
         | I read the article as an unreasonably deep dive into something
         | that few people care about as much as the author. I certainly
         | don't, but that's what makes it good. That's perfect for HN.
        
           | mattkrause wrote:
           | My only real beef with the article is that "Uneasy about
           | easing functions" would have been a much better title.
        
             | pahgawk wrote:
             | Author here -- kicking myself because this is way better
             | lmao
        
               | ziml77 wrote:
               | You should edit the title. I'm sure there's plenty of
               | people who will find this post later on and be tickled by
               | that :)
        
               | mattkrause wrote:
               | Take it--it's all yours :-)
        
             | Bluestein wrote:
             | Oh, you beat me to it, I see :)
             | 
             | Kudos.-
        
               | mattkrause wrote:
               | Great minds, etc!
        
               | Bluestein wrote:
               | Totally :)
               | 
               | PS. And, if I may as a recovering Flash 5/Actionscript
               | victim ...
               | 
               | ... this (great) article brought back memories.-
        
           | f33d5173 wrote:
           | It didn't seem unreasonably deep at all. It was long, sure,
           | but it seemed to only scratch the surface of the topics it
           | was discussing. That was sort of my point in bringing up the
           | css function - it is itself incredibly bare-bones, but just
           | describing it's usage would have covered more ground imo.
        
             | shermantanktop wrote:
             | "Unreasonably deep" is a relative term. Certainly deeper
             | than I care to go. But sure, it could be unreasonably
             | deeper.
             | 
             | Every time I have used animation my approach has been to
             | treat it as frosting to be used sparingly. As such I would
             | be much more attracted to simple/supported modes (that
             | someone else will be interested in keeping functional) than
             | I would be to obsessing over physics realism. But I am also
             | a UI caveman with no taste, so there's that.
        
         | ajkjk wrote:
         | how would any of that make the article ridiculous?
        
           | f33d5173 wrote:
           | It circles around the point without ever reaching it. Each
           | section seemed like it was missing the obvious. "To me"
           | meaning that was my personal impression.
        
         | jakelazaroff wrote:
         | By "CSS version" I'm assuming you mean cubic-bezier [1], which
         | definitely does not solve all the author's problems. For
         | example, you cannot use it to create their third example
         | (easeOutElastic), nor many of Apple's kinematic easing
         | functions or the feedback control.
         | 
         | [1] https://developer.mozilla.org/en-US/docs/Web/CSS/easing-
         | func...
        
           | f33d5173 wrote:
           | Yes, you can't use it to create those other functions, but
           | you can use it to fulfill the authors purported goal in using
           | those other functions. It also solves the deficiencies the
           | author highlights in those other approaches. You could of
           | course point to deficiencies in it and seek to resolve those
           | deficiencies, but that wasn't how the article was structured.
        
             | jakelazaroff wrote:
             | I'm not sure why you think that? The author defines "easing
             | functions" like this (which describes CSS's `cubic-
             | bezier`):
             | 
             |  _> An easing function takes in a linear progress value,
             | and returns a new progress value, but converted to
             | nonlinear motion._
             | 
             | They then describe the problem with them in the section
             | "Easing is not so easy", after introducing easing functions
             | that are already _more expressive_ than `cubic-bezier`:
             | 
             |  _> In traditional animation, the principles are just
             | guidelines; you still end up creating new unique motion
             | each time based on what acting the scene calls for. Easing
             | functions in code don 't quite give you the flexibility to
             | do that._
        
       | bhk wrote:
       | Oscullation/"anticipation" in transitions is so gimmicky and
       | cartoonish. Living things don't move like that, and mechanical
       | things don't unless they are broken, chintzy, or poorly designed
       | (underdamped).
        
         | nilamo wrote:
         | Sure they do? When people do a standing jump, they first crouch
         | lower to the ground. An arrow is pulled back on the bow before
         | fired. A ball pushed uphill will roll uphill before stopping
         | and rolling downhill.
        
           | pc86 wrote:
           | Eh, sort of. You do that if you're working out, because
           | you're trying to maximize performance.
           | 
           | Most living beings aren't trying maximize performance,
           | they're trying to maximize survival. That crouch gives away
           | that you're about to jump, and it allows prey to avoid you
           | more easily or predators to adjust their attack to counter
           | for it. A rabbit trying to get away from a predator simply
           | bounds away in its given direction without giving away what
           | its doing.
        
             | nilamo wrote:
             | My experience seeing animals is apparently different from
             | yours. The anticipation/tell is very clear for a wide range
             | of animals... Birds squat down before taking off, cats
             | hunker down to the ground before pouncing, etc.
             | 
             | Even the human jumping example again... Suggesting people
             | only bend their knees for performance would mean the
             | "normal" way of jumping involves keeping your legs straight
             | at all times and using your ankles/toes for all your
             | thrust?
        
           | fidotron wrote:
           | Those are distinct actions though.
           | 
           | "Anticipation" in character animations is a source of
           | persistent friction between game programmers and animators
           | because if incorporated as part of user/player action it
           | simply kills responsiveness. OTOH being able to see NPCs
           | prepare to do something (like pulling the bow) is incredibly
           | useful.
        
         | thomascountz wrote:
         | Think of a slingshot? Or a person jumping?[1].
         | 
         | We see this, not only in mammals and muscles, but in organic
         | systems which evolved to trade speed for power by storing
         | mechanical, electrical, or chemical potential energy over time.
         | 
         | Overshoot and damping is the same in reverse: dissipating
         | kinetic energy when you, for example, bend your knees when you
         | land from a jump (hopefully).
         | 
         | [1]: https://www.youtube.com/watch?v=qN3apht8zRs&t
        
       | jcalx wrote:
       | Apple's easing function (like others) is parameterized by
       | physical characteristics (e.g. spring force, damping) that are
       | easier to model from first principles, but there are other
       | parameters (overshoot distance, anticipation size, animation
       | time) that are more useful for animation. A closed-form
       | parametrization with the latter might be tricky to derive, but
       | some kind of iterative solver (plug in desired animation
       | parameters, get values for the physical parameters) shouldn't be
       | too difficult?
        
       | Liftyee wrote:
       | As an engineer I'm attracted towards the PID based one, but also
       | wary of the amount of CPU cycles used just for a little
       | animation. It seems like overkill, for some reason.
        
         | MITSardine wrote:
         | I don't imagine stepping through the ODE with finite
         | differences at the same time step as drawing should be very
         | expensive, essentially it's a handful of sums and products. In
         | fact, using a closed form solution with an exponential is
         | probably more expensive.
        
           | EsportToys wrote:
           | A middleground is to use fixed timesteps with the closed form
           | solution. Then the integration factors can be statically
           | precomputed as constants, and every frame becomes just a 2x2
           | matrix multiplication.
           | 
           | And even if you are to calculate the integration factors
           | based on dynamic frame rates, they only need to be computed
           | just once per frame for all objects that share the same
           | damping configuration.
        
           | pahgawk wrote:
           | You're right, it's not that expensive! The main limiting
           | factor for me is that not all animations play monotonically
           | forward in time. I'm also interested in using these in
           | animation software where you have a timeline and can seek
           | anywhere. So a closed form is helpful in handling that case
           | too.
        
       | thomascountz wrote:
       | The section on feedback control reminded me of procedural
       | animation where you don't calculate the velocities and positions
       | directly; instead the animation is a consequence of constraints
       | and a target.
       | 
       | I took your PD controller concept and added anticipation using
       | two targets: the original mouse target, and an "anticipation"
       | target set proportionally based on the distance from the point to
       | the main target[1].
       | 
       | This also made me think of Jelly Car and the amazing simulations
       | they did using rigid frames for soft bodies, called Shape
       | Matching[2]. Instead of simulating the soft body physics
       | directly, they used a frame, springs, and "gas" to constrain
       | points, which moved towards targets fixed to the frame.
       | 
       | [1]: https://editor.p5js.org/Thomascountz/sketches/YXWm_VV6s
       | 
       | [2]: https://www.gamedeveloper.com/programming/deep-dive-the-
       | soft...
        
         | pahgawk wrote:
         | Author here! Nice, thanks for taking the time to create that
         | demo! I also like the look of commenting out `vel.set(0, 0)`
         | when the anticipation target is reached, as it has less "snap"
         | between velocities. Although if you keep velocity the same, now
         | it'll go a little farther than the anticipation target. So
         | maybe if you wanted to have a specific distance of anticipation
         | (I think something an animator would reasonably want to do),
         | one could do some math to figure out where to place the target
         | position so that by the time it decelerates to 0, the distance
         | is the real anticipation distance.
        
       | fidotron wrote:
       | Honestly, I think once you are tired of easing functions you are
       | best off going to real physics. (By which I mean a simple Verlet
       | integrator).
       | 
       | I've posted this before for other reasons but
       | https://www.luduxia.com/showdown/ - in this case everything is
       | easing functions, except for, bizarrely, the giant text that
       | announces win/draw and the text inside the counter, which is done
       | with actual physics because that proves better, especially with
       | constantly moving targets.
        
       | franciscop wrote:
       | I also didn't like when a new easing happened _while_ another
       | easing was happening, which often felt very jerky. Had to do a
       | bunch of calculus (derivatives) by hand and wrote a small library
       | for it in JS:
       | 
       | https://github.com/franciscop/ola
       | 
       | Note: ola means (sea) wave in Spanish
        
         | pahgawk wrote:
         | Thanks for sharing this library! Author of the post here, I'll
         | definitely check out your implementation.
        
           | franciscop wrote:
           | Thanks! From your article, you might not want/like my library
           | since it's based on a single easing function. I used a cubic
           | function to find out the interpolation values, and the
           | derivative to make sure it's always smooth. The equation
           | looks like this, it's on the source code:
           | 
           | https://www.wolframalpha.com/input/?i=x+%3D+2+*+t+%5E+3+-+3+.
           | ..
           | 
           | If you wanted some more details please feel free to ping me
           | (email through my website's resume, or Twitter) and I'll dig
           | the handwritten equations.
        
       | bsimpson wrote:
       | > maybe I can start by just writing up my rant, and maybe someone
       | else will read this and find a Research Project in here and will
       | make the time before me
       | 
       | This is one of the things I find fascinating about Bret Victor.
       | In the early 10s, he was giving a lot of really influential talks
       | on creative coding. Someone asked him what his motivation was. He
       | essentially said that he gives his ideas away, because he wants
       | to live in a world where they exist. It's easy enough to build
       | enough of a demo to give a talk, but he wanted someone else to do
       | the legwork to grow it into a full project.
        
         | shermantanktop wrote:
         | That runs counter to conventional wisdom about patents: very
         | few ideas are worth protecting, because they have zero value
         | until they have been built into something of value in the real
         | world.
         | 
         | And most builders are most passionate about their own ideas. An
         | idea "gifted" from someone else may actually have _negative_
         | value.
        
       | ajkjk wrote:
       | imo there just need to be a few more default easing functions,
       | the standard ones aren't quite natural enough. There must be a
       | standard curve equivalent to the "human pushing/pulling an object
       | from A->B" function that would actually look natural.
       | EaseIn/EaseOut/etc is never quite it; human motion has a bit of
       | higher-order feedback used to regulate it. Maybe to do with the
       | combination of: all the motion happens via muscular springs,
       | plus, there's a well-trained system that regulates the motion to
       | minimize inefficient use of energy. Whether I jerk suddenly and
       | then stop it, or move it slowly so it smoothly decelerates to the
       | final point, it never looks as mechanical as the stuff you see in
       | code.
        
         | eviks wrote:
         | And the parameters should be tied to reality as well like
         | object weight, surface tension, hand strength, ...?
        
           | ajkjk wrote:
           | If you want? I don't care about the parameters, I just think
           | the default functions should include some more sensible
           | options that look less mechanical.
        
       | x187463 wrote:
       | I have found myself leaning heavily on easing functions to smooth
       | motion within my terminal visual effects engine. I do not have a
       | very strong math background so I am limited in how much I can
       | modify the commonly available functions. I have found it useful
       | to create custom easing functions by mapping the easing function
       | progress across a bezier curve. There's an example in the
       | changeblog write-up from the last release:
       | 
       | https://chrisbuilds.github.io/terminaltexteffects/changeblog...
        
       | MITSardine wrote:
       | Interesting article. But why is it an issue for it to be
       | iterative?
       | 
       | I would imagine you're going to step through time anyways, to
       | draw frame after frame. Wouldn't it in fact be cheaper to step
       | through using some finite differences scheme, with one FD step
       | for one draw step? It could be as cheap as a handful of additions
       | per time step. Unless I'm overlooking something?
       | 
       | If needed for stability or accuracy, you can also step through
       | several FD steps in one frame, but I'd imagine at a rate of
       | 20fps, this should not be necessary for the types of equations
       | considered.
        
         | pahgawk wrote:
         | Hi, author here! Two things come to mind:
         | 
         | - Part of my use case is that I build animation software. In
         | there, you've got a timeline, and you can seek anywhere on the
         | timeline. So in that scenario, you're not always moving
         | consistently forward in time.
         | 
         | - In real-time contexts, sometimes you drop frames, even for
         | simple motion, just due to the hardware it's being run on and
         | what else the computer is doing. Simulations can be sensitive
         | to time steps and produce slightly different results depending
         | on them. The size of the issue depends on a lot of factors, but
         | you don't have that issue at all with a closed form solution.
        
           | MITSardine wrote:
           | I see!
           | 
           | For your second point, you can decouple ODE time stepping and
           | frame time stepping. I think it suffice to step until the
           | lowest time ODE time step that is greater than the current
           | frame time and interpolate between that and the previous ODE
           | time step.
           | 
           | This technique is used in loosely coupled systems, for
           | instance in mechanics where a rigid body needs a much lower
           | time step (higher frequencies) than a soft body to compute
           | the dynamics of, but you still need common time steps to
           | compute interactions. Often times, the time steps are
           | dictated by CFL conditions, and they may not even be integer
           | multiples of each other.
           | 
           | However your first point is where I see the iterative
           | approach really wouldn't work. Especially if the user might
           | change the parameters before you've done anything with them,
           | it wouldn't make sense to precompute values using the
           | iterative scheme. Otherwise, that could be done, and then
           | values interpolated between steps.
           | 
           | If you have few parameters, one solution that comes to mind
           | if you cannot find a closed form solution is to grid the
           | params space, and precompute the curve at each point of the
           | grid. Then, when the user requests any value, simply localize
           | that in the grid and interpolate from the nodes of the
           | element. It becomes problematic if start and end points are
           | parameters, though... In that case I suppose a linear
           | transform of the curve to fit the end points precisely would
           | be in order. You can consider the end points alone, it
           | wouldn't be very complicated.
           | 
           | An improvement would be an adaptive grid; each time a point
           | is inserted in a hypercube, compute also at the projections
           | of that point on the hypercube's facets (and then the
           | projection of that onto the facets' facets, and so on...),
           | and split it. Consider whether to insert based on an
           | indicator that takes into account the solutions at the nodes
           | of the initial hypercube (if they are too distinct, a split
           | is in order). Maybe this is too much complication for
           | something this simple, but anyways there would be solutions
           | for using more difficult ODEs that don't have closed-form
           | solutions. Note if a single family of ODEs is considered,
           | then this can be done offline, or online but cached.
           | 
           | There are more sophisticated methods like PINNs of course,
           | but I don't know if you'd gain anything in performance versus
           | a bespoke scheme. In particular if the inference step is more
           | expensive than localizing in a kd-tree and interpolating from
           | a few points.
        
         | pgorczak wrote:
         | I guess the issue is having to store the intermediate state
         | somewhere. It's true for the PID example that numerical
         | integration is easier to compute - if you look at the comment
         | with the closed form solution, you need trigonometric and
         | exponential functions to evaluate it. It's kind of fascinating
         | that the iterative method approximates the same thing with just
         | addition and multiplication.
        
           | MITSardine wrote:
           | At the same time, the cos and exp are also computed using
           | addition and multiplication. Unless the values are tabulated,
           | I imagine you'd use a series expansion. Or an even more
           | straightforward argument is computers only know how to do
           | addition and multiplication...
           | 
           | In the case of the exponential, if you're willing to start
           | from a known value (say 0, where exp(0) = 1) and need values
           | until the last, then using the very definition of the
           | exponential is even more straightforward... this is the only
           | function s.t. f' = f and f(0) = 1. In other words, step
           | through it! The most natural definition of the exponential is
           | as an ODE to begin with.
           | 
           | Tangentially related, this is one of my favourite articles
           | "Nineteen Dubious Ways to Compute the Exponential of a
           | Matrix":
           | 
           | https://www.cs.jhu.edu/~misha/ReadingSeminar/Papers/Moler03..
           | ..
        
       | sixthDot wrote:
       | Basically any transfert function that is used as interpolator can
       | also be used as "easing". E.g a quadratic Bezier (let's say with
       | empirically determined coeffs). One lesser known I used to like
       | much is the super ellipse, although very costly.
        
       | socalgal2 wrote:
       | Why does literally every single article on easing functions
       | mention Penner? First off he didn't invent them. Games had been
       | using those functions since at least the 80s.
       | 
       | Second, why only him and these functions? I don't write: In
       | JavaScript by Brendan Eich using Node.js by Ryan Dahl I installed
       | a package using npm by Isaac Z. Schlueter called React by Jordan
       | Walke and for the backend I used TJ Holowaychuk's express.js.
       | Instead just write: In JavaScript using node.js I installed react
       | and express.js
       | 
       | But literally, I've never read an article about easing functions
       | that just says "easing functions". they all feel obligated to
       | mention Penner" Why? and no, it's not because open source or
       | multiple contributors. I used those examples because I can't name
       | the 1000s of people for functions which is precisely my point
        
       | istjohn wrote:
       | I'd like to see a toggle switch easing function. Slow down as you
       | approach 40%, then snap to 100%.
        
       | spankalee wrote:
       | There are a lot of post and talks out there about why spring is
       | easier to use and gives nicer results than most easing functions.
       | 
       | In CSS, there's a long standing feature request to add a spring()
       | timing function: https://github.com/w3c/csswg-drafts/issues/280
       | 
       | This would not only be great for developer ergonomics, but would
       | remove JS from the animation path for these cases.
        
       | Bluestein wrote:
       | > I'm unsatisfied with easing functions
       | 
       | Er ... "un ... _eased_ "? :)
        
       | SimplyUnknown wrote:
       | I have the feeling that B-splines would be a good solution for
       | this problem. Given that they have a continuous zeroth (i.e., the
       | function is continuous), first, and second derivative, the motion
       | will always be smooth and there will be no kinks. However, maybe
       | it's moving the problem because now you must tune the
       | coefficients of the B-spline instead of damping parameters (even
       | though a direct mapping between these must exist but this mapping
       | may not be trivial).
        
       ___________________________________________________________________
       (page generated 2025-07-23 23:00 UTC)