FMath::InterpSinInOut outputs invalid results for differing values of A and B

I’ve been wondering why FMath::InterpSinInOut wasn’t working in my use case so I decided to explore some more and ended up writing a quick test program to play around with it to output valid results. Here are my findings:
Original Version:

template< class T >
static FORCEINLINE_DEBUGGABLE T InterpSinInOut(const T& A, const T& B, float Alpha)
{
	return (Alpha < 0.5f) ?
		InterpSinIn(A, B, Alpha * 2.f) * 0.5f :
		InterpSinOut(A, B, Alpha * 2.f - 1.f) * 0.5f + 0.5f;
}

This gives output as to the following with Alpha increasing by 0.1 from 0.0 to 1.0 with different values of A and B:

A=0.0, B=1.0
0.0-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOut:0.00, 0.02, 0.10, 0.21, 0.35, 0.50, 0.65, 0.79, 0.90, 0.98, 1.00,

A=0.5, B=1.0
0.5-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOut:0.25, 0.26, 0.30, 0.35, 0.42, 0.75, 0.83, 0.90, 0.95, 0.99, 1.00,

A=0.25, B=0.75
.25-.75 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOut:0.13, 0.14, 0.17, 0.23, 0.30, 0.63, 0.70, 0.77, 0.83, 0.86, 0.88,

As you can plainly see it reports invalid results if A is not 0.0 and/or if B is not 1.0.

I have derived two different fixes for this issue and before I submit a pull request to github for this issue I would like to know which version would be preferred.

Version1:

template< class T >
static T InterpSinInOutMod1(const T& A, const T& B, float Alpha)
{
	return
		(1.f - Alpha) * (InterpSinIn(A, B, Alpha)) +
		Alpha * (InterpSinOut(A, B, Alpha));
}

Results:

A=0.0, B=1.0
0.0-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu1:0.00, 0.03, 0.10, 0.21, 0.35, 0.50, 0.65, 0.79, 0.90, 0.97, 1.00,

A=0.5, B=1.0    
0.5-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu1:0.50, 0.51, 0.55, 0.61, 0.67, 0.75, 0.83, 0.89, 0.95, 0.99, 1.00,

A=0.25, B=0.75
.25-.75 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu1:0.25, 0.26, 0.30, 0.36, 0.42, 0.50, 0.58, 0.64, 0.70, 0.74, 0.75,

Version 2:

template< class T >
static T InterpSinInOutMod2(const T& A, const T& B, float Alpha)
{
	return 
		0.5f * (InterpSinIn(A, B, Alpha)) +
		0.5f * (InterpSinOut(A, B, Alpha));
}

Results:

A=0.0, B=1.0
0.0-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu2:0.00, 0.08, 0.18, 0.28, 0.39, 0.50, 0.61, 0.72, 0.82, 0.92, 1.00,

A=0.5, B=1.0
0.5-1.0 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu2:0.50, 0.54, 0.59, 0.64, 0.69, 0.75, 0.81, 0.86, 0.91, 0.96, 1.00,

A=0.25, B=0.75
.25-.75 :0.0   0.1   0.2   0.3   0.4   0.5   0.6   0.7   0.8   0.9   1.0
------------------------------------------------------------------------
SinInOu2:0.25, 0.29, 0.34, 0.39, 0.44, 0.50, 0.56, 0.61, 0.66, 0.71, 0.75,

I, personally, prefer the first version based on the alpha value passed in rather than the mean calculation in the second version.

Hi ,

I ran some quick tests and was able to see the same results that you described in your post. If you have not already done so, please feel free to submit a pull request for your preferred fix. We can tweak that if necessary, but it is probably fine as is. If you would prefer not to submit a pull request, I can put in a ticket for this issue to be fixed internally.

Submitted last week: PR1445

A fix has been committed to the dev-blueprints branch. It has been labelled as 4.11 so it should be integrated presently.

Thanks again for your bug report.