#if (XNA)
using Microsoft.Xna.Framework;
#endif
namespace FarseerGames.FarseerPhysics.Mathematics
{
/// <summary>
/// Encapsulates the logic to do bilinear interpolation
/// .V1 .V4
/// .V2 .V3
/// </summary>
public class CircularInterpolator
{
private const float _twoOverPi = 1f/MathHelper.PiOver2;
private float _circleValue1;
private float _circleValue2;
private float _maxValue = float.MaxValue;
private float _minValue = float.MinValue;
private float _value1;
private float _value2;
private float _value3;
private float _value4;
public CircularInterpolator(float value1, float value2, float value3, float value4, float minValue,
float maxValue)
{
_value1 = value1;
_value2 = value2;
_value3 = value3;
_value4 = value4;
_minValue = minValue;
_maxValue = maxValue;
}
public float GetValue(Vector2 position)
{
return GetValue(position.X, position.Y);
}
public float GetValue(float x, float y)
{
float theta;
float lerpValue;
float value = 0;
float d = MathHelper.Distance(x, y);
//quadrant 1
if (x > 0 && y > 0)
{
theta = Calculator.ATan2(y, x);
lerpValue = theta*_twoOverPi;
_circleValue1 = MathHelper.Lerp(_value1, _value2, lerpValue);
_circleValue2 = MathHelper.Lerp(_value3, _value4, lerpValue);
value = MathHelper.Lerp(_circleValue1, _circleValue2, (1 - d)*.5f);
}
if (x < 0 && y > 0)
{
theta = Calculator.ATan2(y, x);
lerpValue = (theta - MathHelper.PiOver2)*_twoOverPi;
_circleValue1 = MathHelper.Lerp(_value2, _value3, lerpValue);
_circleValue2 = MathHelper.Lerp(_value4, _value1, lerpValue);
value = MathHelper.Lerp(_circleValue1, _circleValue2, (1 - d)*.5f);
}
if (x < 0 && y < 0)
{
theta = Calculator.ATan2(y, x) + MathHelper.TwoPi;
lerpValue = (theta - MathHelper.Pi)*_twoOverPi;
_circleValue1 = MathHelper.Lerp(_value3, _value4, lerpValue);
_circleValue2 = MathHelper.Lerp(_value1, _value2, lerpValue);
value = MathHelper.Lerp(_circleValue1, _circleValue2, (1 - d)*.5f);
}
if (x > 0 && y < 0)
{
theta = Calculator.ATan2(y, x) + MathHelper.TwoPi;
lerpValue = (theta - 3*MathHelper.PiOver2)*_twoOverPi;
_circleValue1 = MathHelper.Lerp(_value4, _value1, lerpValue);
_circleValue2 = MathHelper.Lerp(_value2, _value3, lerpValue);
value = MathHelper.Lerp(_circleValue1, _circleValue2, (1 - d)*.5f);
}
if (x == 0 && y > 0)
{
value = MathHelper.Lerp(_value2, _value4, (1 - y)/2f);
}
if (x == 0 && y < 0)
{
value = MathHelper.Lerp(_value4, _value2, (1 + y)/2f); //1--y
}
if (x > 0 && y == 0)
{
value = MathHelper.Lerp(_value1, _value3, (1 - x)/2f);
}
if (x < 0 && y == 0)
{
value = MathHelper.Lerp(_value3, _value1, (1 + x)/2f); //1--y
}
value = MathHelper.Clamp(value, _minValue, _maxValue);
return value;
}
}
}