1

In my program I got a vector matrix. This vector contains the x, y and z coodinates of points. To simplify the programm the z coordinates do not change. Now I got a variable called infill. The idea is that the coordinates of the points form a conture. The variable infill defines the gap between the contur and a smaller contur of the model. To illustrate this here picture:enter image description here

As you can see I get the conture of the model and a smaller contur. For rectangles it's working fine. But it's just a special case. If I use it on a circle it's not working anymore.

So my idea was to check with if-statements. Because I have at least for conditions, I would have to check 16 if statements.

case 1  x<0 y<0 x<infill y<infill
case 2  x<0 y<0 x<infill y>infill
case 3  x<0 y<0 x>infill y<infill
case 4  x<0 y<0 x>infill y>infill
case 5  x<0 y>0 x<infill y<infill
case 6  x<0 y>0 x<infill y>infill
case 7  x<0 y>0 x>infill y<infill
case 8  x<0 y>0 x>infill y>infill

case 9  x>0 y<0 x<infill y<infill
case 10 x>0 y<0 x<infill y>infill
case 11 x>0 y<0 x>infill y<infill
case 12 x>0 y<0 x>infill y>infill
case 13 x>0 y>0 x<infill y<infill
case 14 x>0 y>0 x<infill y>infill
case 15 x>0 y>0 x>infill y<infill
case 16 x>0 y>0 x>infill y>infill

If I also check if x or y are equal to 0 or infill I would have about 87 cases. Now my problem is, that if I use if/else if/else statements my could would be a pain in the ase to read, even if I comment on everythin. Because I have to do this for every element in the vector I'm using a for-loop.

My Qustion to the community is: Is there an intelligent way to handle all this cases. Is the if-statement the best? Or is it better to use switch/case? Here my problem is I don't know how to use switch with a vector of doubles and an integer variable.

Edit: Regarding to the comments here's the code for one case

int size=matrix.size();
for(size_t i=0; i<size; i++) {
   if(matrix[i][0] < 0) {
     if(matrix[i][1] < 0){
       if(matrix[i][0] < (infill*(-1))) {
         if(matrix[i][1] < (infill*(-1))) {
            matrix.push_back(std::vector<double>(3, 0));
            r = matrix.size()-1;
            matrix[r][0]=matrix[i][0]+infill;
            matrix[r][1]=matrix[i][1]+infill;
            matrix[r][2]=matrix[i][2];
         }
         else if(matrix[i][1] > (infill*(-1))) {
            matrix.push_back(std::vector<double>(3, 0));
            r = matrix.size()-1;
            matrix[r][0]=matrix[i][0]+infill;
            matrix[r][1]=(matrix[i][1]+infill)*(-1);
            matrix[r][2]=matrix[i][2];
         }
        }
       }
      }
     }

So I'm checking witch case belongs to the x and y value and then calculate the the coordinates for the inner conture. Furthermore, I can not be sure that all points always group around the origin.

user3794592
  • 183
  • 2
  • 16
  • Are the shapes always able to be centered on a (0,0) origin like that? It seems like you could just reduce the magnitude of all the coordinates by 50% for example, and have a shrunken shape. Maybe I'm not really clear on what the transformation is meant to be--non-rectangle examples might help. Also listing out what you'd actually do in each of the 16 cases would help. – John Zwinck May 11 '16 at 11:46

2 Answers2

1

They way you lay it out, each condition can be represented as a single binary digit in a four-digit binary number. Realizing that it's easy to see how the conditions (with a couple of shifts) can be made into a single number that can be used either as indexes into a table or for a switch statement.

If you want to extend the number of cases, i.e. adding more "bits" then a table-solution seems like the best way to go. Since you don't say what is supposed to happen if each "case" is true or false, I can't really say what the elements should be in the table. If you should do different things for each "case", then having a table of callable objects might be a good idea.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

Correct me if I'm wrong but essentially you want to create contour from vector matrix and a smaller one - resized with offset named infill, which is a distance between points Pn and Pn' ( Pn' is Pn after resize). I made this assumption looking at left right corner of the picture above. Moreover I suppose that all points in matrix are in order - which means that there is an actual line between point Point_n and Point_n+1 not between random points. Knowing all of that you do not want to create more complex if statement but create an algorithm resizing polygon by threshold.

The easiest one I could imagine is to:

  • Find all closed polygons in polygon you have stored in vector matrix
  • For each polygon you want to find it's inside
  • For each polygon, for each angle you want to find bisector
  • For each point Pn in angle you found bisector you want to move it by 'infil' (create Pn' point) in direction of polygon inside

Remember that in switch case you can only use compilation constant variables, which means you can't use switch case here.

If I understood you right that this question relates to: Scaling an arbitrary polygon Which means you should look at Angus Johnson and solutions in link he passed: An algorithm for inflating/deflating (offsetting, buffering) polygons Which has a lot of elaborates on that topic.

Community
  • 1
  • 1
pholat
  • 467
  • 5
  • 20