4
\$\begingroup\$

I have not used C++ in quite a while and looking for advice/feedback, the code below implements the Marching Squares Algorithm which is detailed here. While the implementation appears correct and gives the same result as the example on the Wikipedia page, I think that some of the code could be improved and I'm looking for general feedback on how. In particular,

  • how I handle vectors
  • the 2x2 sliding matrix that moves across the test data
  • where I OR in a value

#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <vector>
using std::vector;
void ApplyThreshold(vector<vector<int>> &Matrix2D, int threshold);
vector<vector<int>> CreateContourMatrix(vector<vector<int>> &pMatrix);
int main()
{
 const int cutOff = 2;//The value on which to base the creation of contours
 vector<vector<int>> matrix;
 //Setup test data
 matrix.push_back(vector<int> { 1, 1, 1, 1, 1 });
 matrix.push_back(vector<int> {1, 2, 3, 2, 1, });
 matrix.push_back(vector<int> {1, 3, 3, 3, 1, });
 matrix.push_back(vector<int> {1, 2, 3, 2, 1, });
 matrix.push_back(vector<int> {1, 1, 1, 1, 1, });
 vector<vector<int>> pMatrix = matrix;
 ApplyThreshold(pMatrix, cutOff);//Establishthe contours
 auto contourMatrix = CreateContourMatrix(pMatrix);//Build contour shapes
 //Print the result
 for (auto contour_row : contourMatrix)
 {
 for (int element : contour_row)
 {
 std::cout << element << '\t';
 }
 std::cout << std::endl;
 }
 return 0;
}
/*
 * Move a 2x2 window across a 2d matrix, calculating contour shapes
 */
vector<vector<int>> CreateContourMatrix(vector<vector<int>> &pMatrix)
{
 vector<vector<int>> contourMatrix;
 //vector<int> rows[5];
 for (int i =0;i<pMatrix.size() - 1;i++)
 {
 vector<int> row;//Should this allocation be moved out of the for loop?
 for (int j=0;j<pMatrix[0].size() - 1;j++)//Assume that all rows of the image are the same size
 {
 int shape = 0;
 if (pMatrix[i][j] == 1)
 shape = shape | 8;
 if (pMatrix[i][j + 1] == 1)
 shape = shape | 4;
 if (pMatrix[i+1][j] == 1)
 shape = shape | 1;
 if (pMatrix[i+1][j+1] == 1)
 shape = shape | 2;
 row.push_back(shape);
 }
 contourMatrix.push_back(row);
 }
 return contourMatrix;
}
void ApplyThreshold(vector<vector<int>> &Matrix2D, int threshhold)
{
 for (auto rowVector : Matrix2D)
 {
 for (auto vectorValue : rowVector)
 {
 if (vectorValue >= threshhold)
 vectorValue = 1;
 else
 vectorValue = 0;
 }
 }
}

This isn't supposed to be a complete implementation, i.e. I don't deal with ambiguous cases or actually create an image of the contours. Any advice appreciated.

JS1
28.8k3 gold badges41 silver badges83 bronze badges
asked Feb 16, 2017 at 7:46
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

A couple miscellaneous things.

I don't think you need the vector<int> for the initialization. eg:

matrix.push_back({ 1, 1, 1, 1, 1, });

You can use references in the for loops, just for good measure. IMO using the type instead of auto makes it easier to read when it's a simple type too.

for (auto& contour_row : contourMatrix)
{
 for (int& element : contour_row)
 {
 std::cout << element << '\t';
 }
 std::cout << std::endl;
}

In CreateContourMatrix() the row vector can come out of the for loop. Use .clear() or .fill() on it inside the loop, then you aren't reallocating.

alecxe
17.5k8 gold badges52 silver badges93 bronze badges
answered Feb 17, 2017 at 1:07
\$\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.