Fixed float interpolation

Added last values check to speedup the code, fixed the Overflow
protection and use 'do while' instead of 'for( , , )' function to
increade speed. All this result in a twice more speed on my tests
This commit is contained in:
VitorBoss 2016-10-28 17:45:05 -02:00
parent 59d6f132cd
commit edb9721f3a
1 changed files with 79 additions and 30 deletions

109
table.ino
View File

@ -376,48 +376,74 @@ int get3DTableValue(struct table3D *fromTable, int Y, int X)
return ( (A * m) + (B * n) + (C * o) + (D * r) ) >> 8;
}
/* Executed a benchmark on all options and this is the results
* Stadard version:141164 20 float version:57456 20.51 simple version:54196 20, Number of loops:2500
* Stadard version:141164 20 float version:29292 20.74 simple version:27568 20, Number of loops:2500
*
//This function pulls a value from a 3D table given a target for X and Y coordinates.
//It performs a 2D linear interpolation as descibred in: http://www.megamanual.com/v22manual/ve_tuner.pdf
float get3DTableValue2(struct table3D *fromTable, int Y, int X)
{
float m, n, o ,p, q, r;
long tempVar1, tempVar2;
byte xMin, xMax;
byte yMin, yMax;
xMin = fromTable->lastXMin + 1;
yMin = fromTable->lastYMin + 1;
for (xMin = fromTable->xSize-1; xMin>=0; xMin--)
{
if(X>fromTable->axisX[xMin]) {break;}
if(xMin>fromTable->xSize-1)
{
fromTable->lastXMin = fromTable->xSize-2;
xMin = fromTable->xSize-1;
}
for (yMin = fromTable->ySize-1; yMin>=0; yMin--)
if(yMin>fromTable->ySize-1)
{
fromTable->lastYMin = fromTable->ySize-2;
yMin = fromTable->ySize-1;
}
do
{
if(Y>fromTable->axisY[yMin]) {break;}
}
if (xMin>fromTable->xSize-1) {xMin = fromTable->xSize-1;} //Overflow protection
if (yMin>fromTable->ySize-1) {yMin = fromTable->ySize-1;} //Overflow protection
if(X>=fromTable->axisX[xMin]) {break;}
xMin--;
}while(1);
fromTable->lastXMin = xMin;
do
{
if(Y>=fromTable->axisY[yMin]) {break;}
yMin--;
}while(1);
fromTable->lastYMin = yMin;
xMax = xMin + 1;
yMax = yMin + 1;
if (xMax>fromTable->xSize-1) {xMax = fromTable->xSize-1;} //Overflow protection
if (yMax>fromTable->ySize-1) {yMax = fromTable->ySize-1;} //Overflow protection
if (xMax>fromTable->xSize-1) //Overflow protection
{
xMax = fromTable->xSize-1;
xMin = xMax - 1;
}
if (yMax>fromTable->ySize-1) //Overflow protection
{
yMax = fromTable->ySize-1;
yMin = yMax - 1;
}
int yMaxValue = fromTable->axisY[yMax];
int yMinValue = fromTable->axisY[yMin];
int xMaxValue = fromTable->axisX[xMax];
int xMinValue = fromTable->axisX[xMin];
p = float(X-fromTable->axisX[xMin]) / float(fromTable->axisX[xMax] - fromTable->axisX[xMin]);
q = float(Y-fromTable->axisY[yMin]) / float(fromTable->axisY[yMax] - fromTable->axisY[yMin]);
p = float(X - xMinValue) / (xMaxValue - xMinValue);
q = float(Y - yMinValue) / (yMaxValue - yMinValue);
int A = fromTable->values[yMin][xMin];
int B = fromTable->values[yMin][xMax];
int C = fromTable->values[yMax][xMin];
int D = fromTable->values[yMax][xMax];
m = (1.0-p) * (1.0-q);
n = p * (1-q);
o = (1-p) * q;
r = p * q;
return ( (A * m) + (B * n) + (C * o) + (D * r) );
}
//This function pulls a value from a 3D table given a target for X and Y coordinates.
@ -426,27 +452,50 @@ int get3DTableValue3(struct table3D *fromTable, int Y, int X)
{
byte xMin, xMax;
byte yMin, yMax;
xMin = fromTable->lastXMin + 1;
yMin = fromTable->lastYMin + 1;
for (xMin = fromTable->xSize-1; xMin>=0; xMin--)
{
if(X>fromTable->axisX[xMin]) {break;}
if(xMin>fromTable->xSize-1)
{
fromTable->lastXMin = fromTable->xSize-2;
xMin = fromTable->xSize-1;
}
for (yMin = fromTable->ySize-1; yMin>=0; yMin--)
{
if(Y>fromTable->axisY[yMin]) {break;}
}
if (xMin>fromTable->xSize-1) {xMin = fromTable->xSize-1;} //Overflow protection
if (yMin>fromTable->ySize-1) {yMin = fromTable->ySize-1;} //Overflow protection
if(yMin>fromTable->ySize-1)
{
fromTable->lastYMin = fromTable->ySize-2;
yMin = fromTable->ySize-1;
}
do
{
if(X>=fromTable->axisX[xMin]) {break;}
xMin--;
}while(1);
fromTable->lastXMin = xMin;
do
{
if(Y>=fromTable->axisY[yMin]) {break;}
yMin--;
}while(1);
fromTable->lastYMin = yMin;
xMax = xMin + 1;
yMax = yMin + 1;
if (xMax>fromTable->xSize-1) {xMax = fromTable->xSize-1;} //Overflow protection
if (yMax>fromTable->ySize-1) {yMax = fromTable->ySize-1;} //Overflow protection
if (xMax>fromTable->xSize-1) //Overflow protection
{
xMax = fromTable->xSize-1;
xMin = xMax - 1;
}
if (yMax>fromTable->ySize-1) //Overflow protection
{
yMax = fromTable->ySize-1;
yMin = yMax - 1;
}
long p, q;
p = ((long)(X-fromTable->axisX[xMin]) <<8) / (fromTable->axisX[xMax] - fromTable->axisX[xMin]);
q = 256 - (((long)(Y-fromTable->axisY[yMin])<<8) / (fromTable->axisY[yMax] - fromTable->axisY[yMin]));
p = ((X - fromTable->axisX[xMax]) << 8) / (fromTable->axisX[xMax] - fromTable->axisX[xMin]); //This is the standard case
q = 256 - (((Y - fromTable->axisY[yMax]) << 8) / (fromTable->axisY[yMax] - fromTable->axisY[yMin]));
int A = fromTable->values[yMin][xMin];
int B = fromTable->values[yMin][xMax];
int C = fromTable->values[yMax][xMin];