2
\$\begingroup\$

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;
 }
 }
 }
 }
asked Oct 24, 2012 at 20:56
\$\endgroup\$
3
  • 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\$ Commented 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\$ Commented 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\$ Commented Oct 25, 2012 at 13:39

1 Answer 1

1
\$\begingroup\$

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.

answered Oct 25, 2012 at 22:17
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.