How do you compare elements of a vector within a 3 Dimensional vector in c++

Viewed 45

I am trying to loop through a three-dimensional vector. I have one vector containing multiple vectors of x and y coordinates. Lets call the parent vector v0, the vector containing the coordinates v1, and the pair of coordinates v2.

For any v2 in any v1, if the x value of v2 is equal to the x value of another v2 in any v1, I want to add the y values of the v2. if a v2 doesn't have any matching y values, add it to the y value at the point in the next v1 (I already have a function that does this)

In the end I only have one v1 which I will render. The size of a v1 is unknown, but will always have some v2 with the same x value as a v2 in another v1

The context is essentially I have a set of graphs that I want to "add" to make fractal noise. I am successfully generating the set of graphs, but am unsure how to add them.

Here is my code so far

(also for those unfamiliar with sfml, sf::vector2f is just a vector of two floats. These are the coordinates. you can access the value of a coordinate with vec.y/vec.x)

void Noise() {
    
    std::vector<sf::Vector2f> finalGraph;
    std::vector<sf::Vector2f> singleNoise;
    std::vector < std::vector<sf::Vector2f>> allGraphVec;


    float persistance = 0.5; 
    int nOOPM1 = 4;
    
    //generates the graphs to be added
    for (int i = 0; i < nOOPM1; i++) {
        float frequency = pow(2, i);
        float amplitude = pow(persistance, i);


        singleNoise = 
            this->generateNoise(frequency, 300 * amplitude);
        allGraphVec.emplace_back(singleNoise);
        
    }
    
    
//Do what I described above over here
//This is pseudoCode I have no idea what Im doing here
for(auto &v : allGraphVec){
    if(v1 has a v2 == to another v1's v2){
         add the v2
         take the added value and put it in finalgraph
    }
}

    
//this function just draws a line between each point in the graph, making it a graph not a series of points
    for (std::vector<sf::Vector2f>& v : allGraphVec) {
        v = this->interpolateNoise(v, 3, 1000);
    }

    //this will be rendered
    this->graphToBeRendered = finalGraph 

    
};

Sorry if this is a bit confusing.

1 Answers

I'm going to answer the question in parts.

  1. So if i understand correctly you have a list of multiple two dimensional points. You currently have this vector: vector<vector<vector<Vector 2f>>> which after translation means you have a list of a list of a list of objects with 2 float values.

What you described in text, from what i understand, is meant to be a vector<vector<vector 2f>> which is a list of lists of objects with two float values.

You can imagine the difference between these lines of code that:

vector<vector<Vector2f>> is a 2D table like in excel where each cell has two values x and y

vector<vector<vector<Vector2f>>> is on the other hand a stacked up version of the previous one on top of each other. So imagine an excel sheet like before, on top of another excel sheet making an excel sheet cube

As you can see this is all getting confusing really quickly...

  1. First things first. Looping...

Easiest way to loop through a vector is to use for(auto &v : vector) and to do it to multiple at the same time:

for(auto &v0 : vector) for(auto &v1 : vector) for(auto &v2 : vector) The above case would be used to loop through the triple vector. For the rest of the answer i'll assume the thing you want to do is the double vector of double floats.

for(auto &v0 : vector)
{
    for(auto &v1 : vector)
    {
        //do the thing
    }

}

To do the task we need to loop through every item in that vector one by one and check if the v2 x exists in another point.

Next is to actually do the thing. We need to find if that number exists in the vector. like going through any list there are many methods some fast some slow. I'll continue using the method i used previously - just plainly going through the vector.

  1. Finding the number x. To find the number x we need to, yes you guessed it go through the vector again. This time to make it less eye straining lets do it in a function:
void findMe(vector 2f &point, vector<vector<vector 2f>> &vec)
{
    bool found = false;
    for(auto &v0 : vec)
    {
        for(auto &v1 : vec)
        {
            if (&v1 != point) //check if we are at the point we are searching
            {
                if (point.x == v1.x)
                {
                    point.y += v1.y; //i think this is what you wanted. you didnt specify what to add to what
                    found = true; // check flag
                }
            }
        }

    }
    
    if (found == false)
    {
        //add to next point. you can do this by going through the loop finding the next element and adding it there, by saving the next element or by sending it to the function as parameter. your choice.
    }
}

  1. Adding to vector. Removing from vector.

You can add something to a vector by using the emplace_back() function.

eg. adding 5 to vector of ints:

vec.emplace_back(5);

when you have objects you can add them via empty constructor:

vec.emplace_back(sf::vector 2f())

vec.emplace_back({2,5})

vec.emplace_back(sf::vector 2f(5,2)) this should work too i think.

to add vector of vectors vec.emplace_back(vector<vector<vector 2f>>())

Removing:

vec.erase(vec.begin() + offset) //where offset is the index of the item in the vector you want to delete.

IMPORTANT!!!:

  • remember you need to add item to vector before you use the item or index.

I hope this answer helps. Comment under this if i made any mistakes. I wrote this all from the top of my head and havent teste it in IDE.

Related