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;
                }
            }
        }
    }
\$\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\$
    – mseancole
    Oct 24 '12 at 21:27
  • \$\begingroup\$ When you say optimized, do you want it to run faster, or do you want less code? \$\endgroup\$ Oct 24 '12 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
    Oct 25 '12 at 13:39
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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.