Ryanas
Ryanas

Reputation: 1827

Increment for loop by variable

I am taking in sound as a float called scaledVol. I wish to change the spacing of the letters being drawn out by scaledVol.

This is the code snippet:

for (int i = 0; i < camWidth; i+=7){
    for (int j = 0; j < camHeight; j+=9){
        // get the pixel and its lightness (lightness is the average of its RGB values)
        float lightness = pixelsRef.getColor(i,j).getLightness();
        // calculate the index of the character from our asciiCharacters array
        int character = powf( ofMap(lightness, 0, 255, 0, 1), 2.5) * asciiCharacters.size();
        // draw the character at the correct location
        ofSetColor(0, 255, 0);
        font.drawString(ofToString(asciiCharacters[character]), f, f);
    }
}

where i sets the width between character spacing and j sets the height between character spacing.

Instead of incrementing by 7 or 9, I would like to increment by a float called scaledVol.

Upvotes: 1

Views: 3695

Answers (3)

lrineau
lrineau

Reputation: 6274

You can use float as the type of the two loop variables, and then cast them to int:

for (float x = 0; (int)x < camWidth; x+=scaledVol) {
  int i = (int)x;
  for (float y = 0; (int)y < camHeight; y+=scaledVol) {
    int j = (int)y;
    // the rest of the code using i and j
  }
}

Be careful that scaledVol has best be greater than 1, otherwise you will have consecutive values of i and j that are equal. Your treatment in `// the rest of the code`` may not like that.

Upvotes: 1

Instead of incrementing by 7 or 9, I would like to increment by a float called scaledVol.

Then code:

 for (int i = 0; i < camWidth; i+=(int)scaledVol){

You may want to take the floor of, and ensure the conversion is done once, the increment; perhaps code instead

 int incr = (int) floor(scaledVol);
 assert (incr > 0);
 for (int i = 0; i < camWidth; i+=incr) {

Read more about floor(3), ceil(3), round(3), and IEEE floating point and rounding errors

Please use your debugger (e.g. gdb) to understand more.

You could use more C++ friendly casts e.g.

 int incr = int(floor(scaledVol));

or static_cast

 int incr = static_cast<int>(floor(scaledVol));

or perhaps even reinterpret_cast

 int incr = reinterpret_cast<int>(floor(scaledVol));

which might not work as you want, particularily if both numerical types have same size.

Upvotes: 3

Ed Heal
Ed Heal

Reputation: 59997

Need something like

for (float i = 0.0f; i < camWidth; i+=scaleVol){

Assuming that camWidth is a float. If not cast it to a float.

This will also over come a problem with rounding errors when converting scaledVol to an int

Upvotes: 1

Related Questions