[Math] How to non-linearly interpolate between 4 values

interpolation

I'm looking for a non-linear way of interpolating between 4 values within a games engine.

I have a unit square abcd. It has a different value for each edge ABCD. Within that square there is some point x. I also have exact position of x within that square in 0..1 range by X and Y axis.

0 --> X
|
V    aAAAAAAAb
Y    D       B
     D   x   B
     D       B
     dCCCCCCCc

Now I need to interpolate between values of ABCD edges in a way, that near the edge the value of x matches the edges value, but farther from the edge it gets mixed with other edges proportionally to the distances.

For example:

// Trivial case - mix proportionally
X = 0.1
Y = 0.1
x = A * 0.45 + B * 0.05 + C * 0.05 + D * 0.45; // Sum = 1

// Near edge case - B and D get penalized
X = 0.1
Y = 0.05
x = A * 0.9 + B * 0.025 + C * 0.05 + D * 0.45; // Sum should be = 1, how?

// Edge case
X = 0.1
Y = 0
x = A * 1.0 + B * 0 + C * 0 + D * 0; // Sum = 1

// Degenerate case
X = 0
Y = 0
x = A * 0.5 + B * 0 + C * 0 + D * 0.5; // Sum = 1

What kind of interpolation formula I could use to get the continuous desired result? Preferably fast in computation (to be used in games render loop).

P.S. This is my first post on Math, so please comment if there are any issues with it.

Best Answer

I have come up with a simpler equation while formulating my question.

Idea is to interpolate between X and Y axis proportionally to distance to them.

Let me guide you through with an example:

// Input
X = 0.5; Y = 0.1

// This is base interpolation that prefers closer edge
x = A * (1-Y) + B * X + C * Y + D * (1-X); // Sum = 2

// Now calculate proportion between distances to edges
distX = 0.5 - Abs(X-0.5); // Distance to edge 0..0.5 range
distY = 0.5 - Abs(Y-0.5); // Distance to edge 0..0.5 range
if distX + distY > 0.001 then //0.001 is to deal with FP precision loss
begin
  distSum = distX + distY;
  coefX := distX / distSum; // 0..1 range
  coefY := distY / distSum; // 0..1 range
end
else
begin
  coefX := 0.5;
  coefY := 0.5;
end;

// Our example values
coefX = 0.5 / 0.6 = 0.83
coefY = 0.1 / 0.6 = 0.17

// Add X/Y weights into equation, to get Sum = 1
x = A * (1-Y) * coefX + B * X * coefY + C * Y * coefX + D * (1-X) * coefY;

// Our example values
x = A * 0.747 + B * 0.085 + C * 0.083 + D * 0.085; // Sum = 1

Sorry I'm not familiar with Excel formulas close enough to build a diagram, but it looks much alike this:

enter image description here

Benefits are: no need for iterations, knowing ABCD values and X Y position of x is enough.