2

I want to know the most basic math principles I need to interpolate a value between 3 or more other values, based on a linear percentage; as it would be applicable in programming.

For example, say I have "0", "100", "200", and I want the number that's at "50%". The math would then return something like "100" because 100 is at 50%.

Another example: I have 3 points somewhere in 3D space. If I do "75%" then the result would be a point that is exactly halfway between point 2 and 3, or if I do "25%" then it'll be half-way between 1 and 2.

Game engines like Unity use something like this for blending between multiple animations on a character, for another example.

What I've brainstormed so far is that I would somehow take the input value and find whatever the 2 neighboring "points" are closest to it (much harder in 3D or 2d space but manageable in 1d), then simply lerp between those two- but that requires me to figure out what percentage both of those points are at individually, and remap from "0 to 100%" to "A% to B%". I think it would work but It seems kind of complicated to me.

If possible, I'd like answers to include a C# example or language-agnostic psuitocode just so I can understand the math.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Fennecai
  • 109
  • 3
  • 13
  • 1
    Your 0, 100, 200 example is one-dimensional. As you provided in the question, it's the percentage difference between 200 and 0. In 3D space, three points don't have to be in a line. They are in a 2D plane. Imagine a triangle on a sheet of paper. What's the definition of 20%? 20% of the distance between point A and the midpoint of the average of point B and point C? – Gilbert Le Blanc Mar 08 '21 at 00:39
  • 1
    google **piecewise interpolation** ... so simply you got parameter in range `t = <0...1>` that is multiplied by number of segments `n` and the fractional part will give you parameter `t'` between selected segment `ix` endpoints/vectors/whatever ... see [Piecewise interpolation cubic example](https://stackoverflow.com/a/22806242/2521214) this one interpolates between points using interpolation cubics (catmull-rom). You can easily use linear interpolation instead if you want ... something like `t'=t*n; ix=floor(t'); t'-=ix;` – Spektre Mar 08 '21 at 07:14
  • @GilbertLeBlanc no; in my case 50% would be exactly at point B regardless of how they are arranged in 2d or 3d space. the goal is to interpolate along the points as if they are "waypoints" along a path. – Fennecai Mar 10 '21 at 15:16
  • @Spektre i dont understand the examples you gave but I'll try to implement this in code somewhere and see if i can figure it out. thanks. Mind posting this as an answer so i can mark it as the accepted answer if it works out? – Fennecai Mar 10 '21 at 15:23

2 Answers2

1

simple example for scalar float objects using piecewise linear interpolation:

int n=3;   // number of your objects
float x[n]={ 0.5,2.0,10.0 };  // your objects

float get_object(float t) // linearly interpolate objects x[] based in parameter t = <0,1>, return value must be the same type as your objects
   {
   int ix;
   float x0,x1; // the same type as your objects
   // get segment ix and parameter t
   t*=n; ix=floor(t); t-=ix;
   // get closest known points x0,x1
   x0=x[ix]; ix++; 
   if (ix<n) x1=x[ix]; else return x0;
   // interpolate
   return x0+(x1-x0)*t;
   }

so if t=0 it returns first object in the x[] if it is t=1 is returns last and anything in between is linearly interpolated ... The idea is just to multiply our t by number of segments or point (depend on how you handle edge cases) which integer part of the result will give us index of closest 2 objects to our wanted one and then the fractional part of multiplied t will give us directly interpolation parameter in range <0,1> between the two closest points...

In case you objects are not with the same weight or are not uniformly sampled then you need to add interpolation with weights or use higher order polynomial (quadratic,cubic,...).

You can use this for "any" type T of objects you just have to implement operations T+T , T-T and T*float if they are not present.

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

If your gameObjects is at the same line try this code.

public Transform objStart;
    public Transform objEnd;
    public Transform square;
    public float distance;
    //percent .5 means 50%
    [Range(0f,1f)]
    public float percent;
    public Vector3 distancePercentPosition;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //get distance between two object
        distance = Vector3.Magnitude(objEnd.position - objStart.position);
        //get position based on percent;
        distancePercentPosition = (objEnd.position - objStart.position).normalized * percent * distance;
        square.position = objStart.position + distancePercentPosition;
    }

once you get the position between lines you can now map your gameobject in each position based on percent.

Art Zolina III
  • 497
  • 4
  • 10
  • you made a few assumptions here that aren't helpful. firstly you assumed i was _only_ asking about unity when I stated otherwise, and you also assumed that my points are always on a straight line, which they seldom are. that said, this is helpful to some cases though, so its not really a bad answer EDIT: well actually i looked at the code now and it seems you also forgot I'm working with multiple points, not just 2 – Fennecai Mar 10 '21 at 15:18
  • ok thats for unity. but the maths are the same for all 3d application it is using vectors for calculations. thats only simple example in c#. when you have different vector position then you have to consider the direction also add all position and when you get the distance just multiply it to 0-1 value example .1 means 10%. – Art Zolina III Mar 10 '21 at 15:38
  • but your code only accounts for a start and endpoint and has nothing to do with my question about multiple points (3 or more, not just a start and end) – Fennecai Mar 10 '21 at 16:32
  • That's only start and the farthest of all points is the end and I believe points in between are all points. For simplicity I make all points straight line. If its not straight line then direction also will take into account. – Art Zolina III Mar 10 '21 at 16:55