 # Exponential interpolation

Hello, I want to attach a Node to other Node with smooth transition. Is there any built in features to use in Urho3d?

I’ve found this formula in case anyone is interested in :

``````       newPosition =  targetPos * alpha + prevPos * (1 - alpha);
``````

Alpha is something like damping factor.

You could just use Easing to get the every interpolation state. There are tons of implementations of different languages

E.g. I use easing function to control the move of camera, any `Urho3D::Node` should be similar -

``````    if (elapsedTime_ <= duration_)
{
float factor = Expo::easeOut(elapsedTime_, 0.0f, 1.0f, duration_); //  (epapsed-time, start-value, end-value, total-time)

if (interpLookAtPos_)
cameraLookAtNode_->SetWorldPosition(lookAtBeginPos_ + (lookAtEndPos_ - lookAtBeginPos_) * factor);
// ...
}
``````

Edit: in your case, you can just the Exponential easing function.

1 Like

The formula you use is linear.

What does Expo mean? How to use it?

Did you look into Urho’s attribute animation capability?

Setting the value animation’s interpolation method to `IM_SPLINE` you might be able to achieve the result you are looking for with the right spline tension.

1 Like

I will take a look. Thank you.

Expo means Exponential.

1 Like

There’s no such thing as straight exponential interpolation.

Do you mean MKCB curves?

M = slope
K = exponent

Is this the thing you’re after?

``````    struct ResponseCurve
{
CurveType type_;
float xIntercept_;
float yIntercept_;
float slopeIntercept_;
float exponent_;
bool flipX_;
bool flipY_;

ResponseCurve() : type_(CT_Linear), xIntercept_(0.0f), yIntercept_(0.0f), slopeIntercept_(1.0f), exponent_(1.0f), flipX_(false), flipY_(false)
{
xIntercept_ = yIntercept_ = 0.0f;
}

float GetValue(float x) const
{
if (flipX_)
x = 1.0f - x;

// Evaluate the curve function for the given inputs.
float value = 0.0f;
switch (type_)
{
case CT_Constant:
value = yIntercept_;
break;
case CT_Linear:
// y = m(x - c) + b ... x expanded from standard mx+b
value = (slopeIntercept_ * (x - xIntercept_)) + yIntercept_;
break;
// y = mx * (x - c)^K + b
value = ((slopeIntercept_ * x) * powf(abs(x + xIntercept_), exponent_)) + yIntercept_;
break;
case CT_Logistic:
// y = (k * (1 / (1 + (1000m^-1*x + c))) + b
value = (exponent_ * (1.0f / (1.0f + powf(abs(1000.0f * slopeIntercept_), (-1.0f * x) + xIntercept_ + 0.5f)))) + yIntercept_; // Note, addition of 0.5 to keep default 0 XIntercept sane
break;
case CT_Logit:
// y = -log(1 / (x + c)^K - 1) * m + b
value = (-logf((1.0f / powf(abs(x - xIntercept_), exponent_)) - 1.0f) * 0.05f * slopeIntercept_) + (0.5f + yIntercept_); // Note, addition of 0.5f to keep default 0 XIntercept sane
break;
case CT_Threshold:
value = x > xIntercept_ ? (1.0f - yIntercept_) : (0.0f - (1.0f - slopeIntercept_));
break;
case CT_Sine:
// y = sin(m * (x + c)^K + b
value = (sinf(slopeIntercept_ * powf(x + xIntercept_, exponent_)) * 0.5f) + 0.5f + yIntercept_;
break;
case CT_Parabolic:
// y = mx^2 + K * (x + c) + b
value = powf(slopeIntercept_ * (x + xIntercept_), 2) + (exponent_ * (x + xIntercept_)) + yIntercept_;
break;
case CT_NormalDistribution:
// y = K / sqrt(2 * PI) * 2^-(1/m * (x - c)^2) + b
value = (exponent_ / (sqrtf(2 * 3.141596f))) * powf(2.0f, (-(1.0f / (abs(slopeIntercept_) * 0.01f)) * powf(x - (xIntercept_ + 0.5f), 2.0f))) + yIntercept_;
break;
case CT_Bounce:
value = abs(sinf((6.28f * exponent_) * (x + xIntercept_ + 1.0f) * (x + xIntercept_ + 1.0f)) * (1.0f - x) * slopeIntercept_) + yIntercept_;
break;
}

// Invert the value if specified as an inverse.
if (flipY_)
value = 1.0f - value;