# Better way to average around points

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;
}
}
}
}

• 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. Oct 24, 2012 at 21:27
• When you say optimized, do you want it to run faster, or do you want less code? Oct 24, 2012 at 22:55
• 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. Oct 25, 2012 at 13:39

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.