What does "linear interpolation" mean? - wpf

I often hear the term "linear interpolation" in context with animations in WPF. What exactly does "linear interpolation" mean? Could you give me an example where to use "linear interpolation"?

Linear means lines (straight ones).
Interpolation is the act of finding a point within two other points. Contrast this with extrapolation, which is finding a point beyond the ends of a line.
So linear interpolation is the use of a straight line to find a point between two others.
For example:
*(5,10)
/
/
/
/
*(0,0)
You can use the two endpoints with linear interpolation to get the points along the line:
(1,2)
(2,4)
(3,6)
(4,8)
and linear extrapolation to get (for example):
(1000,2000)
(-1e27,-2e27)
In animation, let's say you have a bouncing ball that travels from the (x,y) position of (60,22) to (198,12) in 10 seconds.
With an animation rate of 10 frames per second, you can calculate it's position at any time with:
x0 = 60, y0 = 22
x1 = 198, y1 = 12
frames = 100
for t = 0 to frames:
x = (x1 - x0) * (t / frames) + x0
y = (y1 - y0) * (t / frames) + y0
Those two formulae at the bottom are examples of linear interpolation. At 50% (where t == 50):
x = (198 - 60) * (50 / 100) + 60
= 138 * 0.5 + 60
= 69 + 60
= 129
y = (12 - 22) * (50 / 100) + 22
= -10 * 0.5 + 22
= -5 + 22
= 17
and (129,17) is the midpoint between the starting and ending positions.

E.g. when you want a storyboard to move an element from one position to another using a fixed speed, then you'd use linear interpolation between the start and end positions.

Related

Ramdomly replace each entry by one of its four neighbours

I iterate through a 100x100 array and pick every time four neighbours (one left of the center node, one above, one right and one below), like in the picture below
the red one is the center node and the blue ones are the neighbours. I struggle to find a convenient way in MATLAB to pick randomly one of the neighbours.
The following assumes that
Each entry is replaced by one of its original neighbours, independently of what happens to other entries.
Each neighbour has the same probability of being picked.
Neighbourhood is defined cyclically. Thus, for example, in the first column the "left" neighbour belongs to the last column.
The code builds a cyclically extended matrix for convenience, and then uses linear indexing to (randomly) select the neighbours.
x = [10 20 30 40; 50 60 70 80; 90 100 110 120]; % example data
x_ext = x([end 1:end 1], [end 1:end 1]); % cyclically extended matrix
ind = bsxfun(#plus, (2:size(x,1)+1).', (1:size(x,2))*(size(x,1)+2)); % linear indices
% of the original matrix in the extended matrix
delta = [-1 1 -size(x_ext,1) size(x_ext,1)]; % possible displacements for neighbours,
% as linear indices
r = delta(randi(4, size(x))); % generate random displacements
result = x_ext(ind + r); % pick neighbours in extended matrix
Example:
>> x
x =
10 20 30 40
50 60 70 80
90 100 110 120
>> result
result =
20 30 70 30
90 100 60 120
50 110 70 40

Unique hash function without any collisions

So I am given a key that is in the format XYYYYZ, where X is a char from 'A'-'Z', YYYY is and int from 0 to 9999, and Z is a char from 'A'-'C'. I am suppose to make a unique hash function without any collisions.
I was told the smallest someone has made is a table size of 780,000 but I have no idea how.
The one I can think of is X-'A' to get a number from 0 to 26 and multiplying that by 100,000 then multiplying YYYY by 10 and then add (Z - 'A')
So Z1025A would be 2,610,250 and L4444C would be 1,144,443
And the make possible combo is 2699993 and / 2,700,000 would have about a 29% usage rate.
But is there any other way to reduce the the size of the table?
just do
((Z - 'A') * 26 + (X - 'A')) * 10000 + YYYY
The smallest possible hash table size for a key in this format is 780000, because there are 26 ways to choose the first character, 10 ways to choose each of the next four, and 3 ways to choose the final character. That is, there are 26 * 10 * 10 * 10 * 10 * 3 = 780000 possible keys. To find a hash function, think of the hash key like a counter. Rearrange the elements like this:
ZXYYYY
Starting with all elements at zero, each of the 'Y' elements rolls over after reaching 9. 'X' rolls over after reaching 25, and 'Z' rolls over after reaching 2. So, we can assign a number to the four 'Y' elements with:
y4 y3 y2 y1 --> y1 + (y2 * 10) + (y3 * 100) + (y4 * 1000)
This part of the key is just a base 10 counter. The remaining pair of elements forms a base 26 counter, and you can assign a number to this pair by assigning a number from 0 to 25 to the first value ('X'), 26 times a number from 0 to 25 to the second, and adding the results:
z x --> x + (z * 26)
For y4 y3 y2 y1 we will get a value from 0 to 9999, and for z x we will get a value from 0 to 675. If we multiply this value by 10000, we can add the value obtained for y4 y3 y2 y1 to get a unique value for the key. That is, the four low order positions count from 0 to 9 in ones, 0 to 90 in tens, 0 to 900 in hundreds, and 0 to 9000 in thousands, while the two high order positions can be viewed as counting from 0 to 6750000 in ten-thousands. This gives a possible 6760000 unique keys with this hash function. But since your specific case limits 'z' to three characters, we only have 3 * 26 = 78 possibilities for z x, and so there are 780000 unique hashes obtainable with this method, and the hash function can then be written:
hval = y1 + (y2 * 10) + (y3 * 100) + (y4 * 1000) + (x + z * 26) * 10000
where y1, y2, y3, y4, x, and z all represent integer values. Or, using C chars:
int y1, y2, y3, y4;
char x, z;
long hval;
hval = y1 + (y2 * 10) + (y3 * 100) + (y4 * 1000) + ((x - 'A') + (z - 'A') * 26) * 10000;
I should add that, converting the characters of the Latin alphabet to integers in this way is not guaranteed to work by the standard, but so long as you have an ASCII or UTF-8 character set it will work.

Matlab finding best fit line from scatter plot but exclude some data points

I use Matlab to find the best fit line from a scatter plot, but I need to delete some data points. For example I am trying to find the best fit line of
x = [10 70 15 35 55 20 45 30];
y = [40 160 400 90 500 60 110 800];
Now I need to delete all y points that value is over 300, and of course deleting corresponding x points, and then make a scatter plot and find the best fit line. So how to implement this?
Now I need to delete all y points that value is over 300, and of course deleting corresponding x points,
There is standard Matlab trick - Logical Indexing (see for example in matrix-indexing):
x = [10 70 15 35 55 20 45 30]; y = [40 160 400 90 500 60 110 800];
filter = (y<300);
y1 = y(filter);
x1 = x(filter);
plot(x,y,'+b',x1,y1,'or');
You can use polyfit (Matlab Doc) function for linear fit:
ff=polyfit(x1,y1,1);
plot(x,y,'*b',x1,y1,'or',x1,ff(1)*x1 + ff(2),'-g');
grid on;
The best way is to logically filter the dataset, then plot it.
NOTE: Data should be in column format. If it isn't, rotate like x'.
filter = (y<300);
x = x.*filter;
x = [zeros(length(x),1),x]; % this is to get the b(0) coefficient
y = y.*filter;
b = x\y;
x = x(:,2); % cleaning up column of zeros
plot(x,y,'bo')
hold on
plot([min(x),max(x)],(b(1)+b(2))*[min(x),max(x)])
hold off
axis tight

Inverse-square law equation

I have a light sensor which reads light intensity from 0 to 4095. I struggling to to write an equation using the inverse-square law of light so that when the light is lowest (let's say lowest ambient light is 50), it returns 1, and if highest (4095), it returns 26, but crucially the increments from 1 to 26 require the light to increase exponentially i.e.:
123 4 5 6 7 8 9 10 ...27
light intensity ->
Any suggestions of an equation? I can't seem to figure it out. Language is C.
You are wanting to divide your 4095 to 50 interval into 25 equal segments (26-1). That would mean the width of each "intensity segment" is:
(4095-50)/25 = 161.8
So if variable x is ranging 1 to 26, your equation for distance would be:
D = sqrt( 1 / (4095 - (x * 161.8)) )
This is from taking Intensity_value = 1/D^2 as the proportion (I say "intensity value" since this doesn't include the proportion constant if it were a real intensity - we're dealing with arbitrary units for this problem).
In other words, if you plotted x on a line and each x value was a distance D from the origin, you'd get the result you are showing for 1 through 26. I am assuming, from your diagram, that the intensity is DECREASING as you go to the right.
You should be able to generalize this for different ranges of intensities and different ranges of corresponding x.
Try the inverse of I = a.R^2 + b with a = 4090/676 and b = -1, where I is the intensity.
I have obtained this by assuming the above function and inserting the value pairs 1,50 and 26,4095 and solving for a and b.
If your intent is to find some exponential function on domain [1,4095] with values in range [1,26] then this will satisfy these conditions:
f(x) = exp [ ( x - 50) * ln( 26) / ( 4095 - 50)]
If your intent is to find function that satisfies inverse square law then since;
this will work:
(f( x))^2 = ( 1 / ( 4095 - ( x * ( 4095 - 50) / 25)) )
f(x) = sqrt( 1 / ( 4095 - ( x * ( 4095 - 50) / 25)) )
I have no idea of physics, but from your explanation I believe you are looking for logarithmic interpolation; this could be done as follows.
y = ln(x-50) * (26 - 1 / ln(4095-50) ) + 1
Here 50, 26 and 1 are used as parameters to stretch and shift the function to map 50 to 1 and 4095 to 26; I hope this helps.

Calculating an index in an array help with algorithm

I'm taking a sprite sheet and splitting it up into an array. I then take that array and rotate the image by a certain granularity and push that onto the end of the array too to pre bake the rotations for faster drawing (no hardware acceleration). The final result looks something like this:
array[0] = frame1 of the animation
array[1] = frame2 of the animation
array[2] = frame3 of the animation
array[3] = frame1 of the animation rotated at 45 degrees
array[4] = frame2 of the animation rotated at 45 degrees
array[5] = frame3 of the animation rotated at 45 degrees
array[6] = frame1 of the animation rotated at 90 degrees
... etc
So now I'm trying to come up with a function that'll return the right element for any angle at the right granularity. For example, say my in-game object is currently rotated 30 degrees and is on frame1 of the animation, I would want array[3]. If I was on frame2 of the animation, I would want array[4]. If the object was rotated 80 degrees and was on frame1, I would want array[6], and so on.
These are the constants I have:
The # of animation frames (pre-rotation)
The # of animation frames (post-rotation)
The Granularity of the Rotations (from 1 to 360, ie granularity of 45 would be the above example).
This is the signature of the function to calculate the frame:
function calculateImageIndex(animationFrame : Number, currentAngle : Number) : Number
Any ideas on how to calculate this? I'm stumped.
nf: total number of frames
gr: granularity of rotation
r: actual angle of rotation
f: actual frame number
i = round(r / gr) * nf + f - 1
n = Number of frames (Pre-rotation)
g = granularity of rotation
r = actual angle of rotation
f = actual frame
I think these are the constants you need and are given.
The first thing we will want to do it find the number of rotations it would take to get to the angle desired. In the above example getting to an angle of 45 would be 1 rotation. 90 degrees = 2 rotations and so on. Let R = number of rotations.
R = r / g This should always be an integer as you should never need an angle that doesn't fit the gratuity you used.
Next we will calculate the starting index of that rotation "group". In your example above the first group with a rotation 0 would start at index 0. 45 degress or 1 rotation would start at index 3. And so on. To do this we need to multiply the number of rotations (R) by the number of frames pre-rotation (n). Let j = the starting index of that rotation group.
j = R * n
The last step would be to figure out how much you must add to the starting index (j) to reach the frame you want. I will assume the first frame will be numbered 1 as in your example above, but if the first frame is numbered 0 then remove the -1 in the algorithm. Let i = the final index.
i = j + (f - 1)
I will be the index you are looking for. To put this together in one algorithm it would look like this.
i = ((r / g) * n ) + (f - 1)
Hope this helps! Let me know if you need my to clarify anything.

Resources