I have a chunk of code that averages around the points of a grid of values and Im trying to figure out if there is a better way to do the averaging. The array itself is 1 dimensional but i am using an x and y and stride to keep track of it in 2d space. Im mainly just trying to figure out if there is a more optimized way to average this or if this is the best way.
Let me know if anything needs clearing up. Thanks for any input!
for (int y=0;y<lockObj.m_iSize[1];y++)
{
for (int x=0;x<lockObj.m_iSize[0];x++)
{
if(m_bShouldSmooth)
{
float avgAround = 0.0f;
if(x == 0)
{
if(y==0)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+x]) / 4;
else if(y==lockObj.m_iSize[1]-1)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x+1)] + pDest[(y-1)*lockObj.m_iStride+(x)] + pDest[(y-1)*lockObj.m_iStride+(x+1)]) / 4;
else
avgAround = (pDest[(y)*lockObj.m_iStride+(x)] + pDest[(y-1)*lockObj.m_iStride+(x)] + pDest[(y-1)*lockObj.m_iStride+(x+1)] + pDest[(y)*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+(x)]) / 6;
}
else if(x==lockObj.m_iSize[0]-1)
{
if(y==0)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+x]) / 4;
else if(y==lockObj.m_iSize[1]-1)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+(x)]) / 4;
else
avgAround = (pDest[(y)*lockObj.m_iStride+(x)] + pDest[(y-1)*lockObj.m_iStride+(x)] + pDest[(y-1)*lockObj.m_iStride+(x-1)] + pDest[(y)*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+(x)]) / 6;
}
else
{
if(y==0)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+(x-1)] + pDest[(y+1)*lockObj.m_iStride+x] + pDest[(y+1)*lockObj.m_iStride+(x+1)] + pDest[(y)*lockObj.m_iStride+(x+1)]) / 6;
else if(y==lockObj.m_iSize[1]-1)
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+x] + pDest[(y-1)*lockObj.m_iStride+(x+1)] + pDest[(y)*lockObj.m_iStride+(x+1)]) / 6;
else
avgAround = (pDest[y*lockObj.m_iStride+x] + pDest[y*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+(x-1)] + pDest[(y-1)*lockObj.m_iStride+x] + pDest[(y-1)*lockObj.m_iStride+(x+1)] + pDest[(y)*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+(x+1)] + pDest[(y+1)*lockObj.m_iStride+(x)] + pDest[(y+1)*lockObj.m_iStride+(x-1)]) / 9;
}
if(this->GetContactForce() > 0){
if(avgAround < pDest[y*lockObj.m_iStride+x])
pDest[y*lockObj.m_iStride+x] = avgAround;
}
}
}
}
-
1\$\begingroup\$ You'll get more useful answers if you include the language you are using in the tags. I can't really tell from the code itself. \$\endgroup\$mseancole– mseancole2012年10月24日 21:27:19 +00:00Commented Oct 24, 2012 at 21:27
-
\$\begingroup\$ When you say optimized, do you want it to run faster, or do you want less code? \$\endgroup\$Danny Kirchmeier– Danny Kirchmeier2012年10月24日 22:55:55 +00:00Commented Oct 24, 2012 at 22:55
-
\$\begingroup\$ Oops sorry! Meant to mention c++ somewhere in there. And I am just trying to determine if there is a better way to do this. By optimized, I mean if there is any cleaner way to do this without slowing it down any. I thought there might be a way with recursion but I couldn't think of how and if it would be any better. \$\endgroup\$Mungoid– Mungoid2012年10月25日 13:39:08 +00:00Commented Oct 25, 2012 at 13:39
1 Answer 1
I'm not into C++, but here's a suggestion for what it is worth. Create a class that encapsulates the array, let's call it Array
. Define an operator[]
method that gives you the value of the element of the array at (x,y); the function returns 0.0 if the coordinates are invalid. Another method, n_points
, returns the number of valid points around (x,y) - ie. 4, 6 or 9. Then you can compute the average using the following function, ignoring where the point (x,y) is located in the array:
float average(const Array &array, int x, int y)
{
return
(array[x-1,y-1] + array[x,y-1] + array[x+1,y-1] +
array[x-1,y] + array[x,y] + array[x+1,y] +
array[x-1,y+1] + array[x,y+1] + array[x+1,y+1])
/ array.n_points(x,y);
}
That won't be more efficient (the reverse probably), but it would be more readable.