Search code examples
c++vector3dpoint

C++ Trying to generate every possible set of points given max/min x/y/z values, n number of points to be in set, and m value to increment by


I posted this question before but I think I explained it very poorly. Essentially, I want to generate all possible point sets of size n containing points inside the area bounded by the origin (0,0,0) and a point (Y1,Y2,Y3) given by the user, with a set value m to increment by.

For example, if n is 3, m is 1, and (Y1,Y2,Y3) is (1,1,1), the generated point sets would be (each row being a set):

(0, 0, 0) & (0, 0, 0) & (0, 0, 0)
(0, 0, 0) & (0, 0, 0) & (0, 0, 1)
(0, 0, 0) & (0, 0, 0) & (0, 1, 0)
(0, 0, 0) & (0, 0, 0) & (0, 1, 1)
(0, 0, 0) & (0, 0, 0) & (1, 0, 0)
(0, 0, 0) & (0, 0, 0) & (1, 0, 1)
(0, 0, 0) & (0, 0, 0) & (1, 1, 0)
(0, 0, 0) & (0, 0, 0) & (1, 1, 1)
(0, 0, 0) & (0, 0, 1) & (0, 0, 0)
(0, 0, 0) & (0, 0, 1) & (0, 0, 1)
(0, 0, 0) & (0, 0, 1) & (0, 1, 0)
(0, 0, 0) & (0, 0, 1) & (0, 1, 1)
(0, 0, 0) & (0, 0, 1) & (1, 0, 0)
(0, 0, 0) & (0, 0, 1) & (1, 0, 1)
(0, 0, 0) & (0, 0, 1) & (1, 1, 0)
(0, 0, 0) & (0, 0, 1) & (1, 1, 1)

.......

(1, 1, 1) & (1, 1, 1) & (1, 1, 1)

This is what I initially tried but it's only really doing what I want for each individual point, and not finding the correct overall sets (pointset is a vector of point objects of size n that has already been created in the main program, with each point initialized to (0,0,0)):

void allPoints(double Y1, double Y2, double Y3, double precision, vector<Point> pointset)
{
int count = pointset.size()-1;

while (count>=0)
{
    while (pointset.at(count).getX()<Y1) //runs through every possible rectangle within rectangle created by given point Y and origin
    {
        while (pointset.at(count).getY()<Y2)
        {
            while (pointset.at(count).getZ()<Y3)
            {
                // insert formula to test each set with here
                pointset.at(count).incZ(precision);

            }
            pointset.at(count).setZ(0);
            pointset.at(count).incY(precision);
        }
        pointset.at(count).setY(0);
        pointset.at(count).incX(precision);

    }
    count--;
}


}

I can go through later and omit any sets that contain duplicate points. In the end I will be going through and testing each point set with a specific formula and then comparing all resulting values, but I know how to do that.

I only really have basic Java/C++ experience and I'm having trouble writing the correct loop, although I feel like the solution here is similar and I'm just missing it. I'm assuming I'd want to use a vector of point objects in this situation.

Any help getting me in the right direction would be much appreciated.


Solution

  • If I understood correctly, you are just counting using base Y1, Y2 and then Y3 and storing the results, so you can use std::list<unsigned short[3]> of size n and count like you would count in base 10 (in when you reach Y1, you reset the row to 0 and set the next one to 1). When an int[3] is full you know you need to empty it and go to the next int[3].

    You'll need a countBase(const unsigned short& base) function that increment a value in every cycle of loop and reset it when it reaches base, then increment the next value. Your program ends when every values in the list are equal to Y1, Y2 or Y3.

    I don't know what you are planning to do with this but you can, on each execution of the loop, display of store the state of the std::list.

    Don't forget that what you are doing is pretty much like counting in your own strange base and storing the result, and it shouldn't be hard

    [EDIT] After looking at your edit, I definitely think you should use only one loop, a container of ushort[3], a way to increment up to base and find a way to keep the result, it would be much easier to read, and it should give you exactly what you want.

    [EDIT] I think it would also be faster to use a std::list and for this kind of project, you probably need some performances.