Beginner Array Question

edited February 28 in Library Questions

I have an array of narrow vertical rectangles. Each rectangle moves randomly back and forth (left to right) across the screen.

When *any of these overlap I want an event to happen, eg. println "overlapping". So far this works fine with 2 rectangles, but only by referring directly to their number and not array indices.

Screen Shot 2018-02-16 at 21.21.04

When I try indexing, I am running into the issue that, when a rectangle is checking if it overlaps another, it is also checking if it overlaps itself, and thus always returns "overlapping". I get what is happening but how to solve it is a little beyond my reasoning abilities.

Would anyone care to offer some tips? Many thanks.

Tagged:

Answers

  • edited February 17

    In theory, for loop i over all rects and for each of them for loop j over all i+1 till the end of the array so that each pair of rect is checked

    • only once and
    • not one against itself or
    • a versus b and later b versus a what would also not be cool.

    Chrisir

  • Thanks for the reply, Chrisir. I've been trying to put this in to practice but failing so far.

  • edited February 25

    post your entire code here as text (not as image)

    for(int i=0; i < array1.length-1; i++) {
       for(int j=i+1; j < array1.length; j++) {
    
                check array index i against j 
    
    
      }
    }
    
  • I corrected it above

  • edited February 27
    import ddf.minim.*;
    Minim minim;
    AudioPlayer groove;
    
    int noRects = 3;
    Rect_Class[] many_Rects = new Rect_Class[noRects];
    
    //Rect_Class myRect1;
    //Rect_Class myRect2;
    
    
    int rectW = 320;
    int rectH = 240;
    
    
    
    
    
    void setup()
    {
      frameRate(30);
      //myRect1 = new Rect_Class(int(random(50, 255)), 0.01, random(1, 10));
      //myRect2 = new Rect_Class(int(random(50, 255)), 0.01, random(1, 10));
      for (int i=0; i<many_Rects.length; i++) 
      {
        many_Rects[i] = new Rect_Class(int(random(50, 255)), 0.01, random(1, 10));
      }
      size(displayWidth, displayHeight);
      noStroke();
    
    
      // we pass this to Minim so that it can load files from the data directory
      minim = new Minim(this);
    
      // loadFile will look in all the same places as loadImage does.
      // this means you can find files that are in the data folder and the 
      // sketch folder. you can also pass an absolute path, or a URL.
      groove = minim.loadFile("strings.mp3");
      groove.loop();
    }
    
    
    
    void draw()
    {
      fill(0);
    
      // for(int i=0; i < array1.length-1; i++) {
      //   for(int j=i+1; j < array1.length; j++) {
      //           check array index i against j 
    
    
      for (int i=0; i<many_Rects.length-1; i++) 
      {
        for(int j=i+1; j<many_Rects.length; j++) 
        {
    
          if (many_Rects[i].overlaps(many_Rects[j])) 
          {  
            fill(255);                      // Turn whole screen white
            println("OVERLAP");                 
          } 
        }
      }
    
    
    
      for(int i = 0; i < groove.bufferSize() - 1; i++)
      {
        line(i, 50  + groove.left.get(i)*50,  i+1, 50  + groove.left.get(i+1)*50);
        line(i, 150 + groove.right.get(i)*50, i+1, 150 + groove.right.get(i+1)*50);
      }
    
    
    
    
    
      //draw the background
      rect(0, 0, displayWidth, displayHeight);
    
    
      for (int i=0; i<many_Rects.length; i++) 
      {
        many_Rects[i].calculate();
        many_Rects[i].display();
      }
    }
    
    
    
    class Rect_Class {
      // declare variable accesible within object instance
      int fill;
      float increment;
      float n;
      float xoff;
      float rectWidth = 64;
    
    
    
    
      //initialise
      Rect_Class(int tempFill, float tempIncrement, float tempxOff){
        // pass public variable into local variable
        fill = tempFill;
        increment = tempIncrement;
    
        // initialise all the other local variables
        xoff = tempxOff;
      }
    
    
      void calculate() {
        // locate point along x-axis (via perlin noise caled yo win..
        n = noise(xoff);
        //println("Noise: " + n);
        n *= displayWidth;  // **************** NB ******************
        //println("Scaled Noise: " + n + '\n');
        //with each cycle, increment xoff
        xoff += increment;
      }
    
    
      void display() 
      {
        // Draw the ellipse at the value produced by perlin noise
        fill(fill);
        rect(n, 0, rectWidth, displayHeight);
      }
    
    
      boolean overlaps(Rect_Class other) 
      {
        float d = abs(n - other.n);
        println(d);
        //println(rectWidth + other.rectWidth);
        if (d <= rectWidth) {
          return true;
        } else {
          return false;
        }
      }
    }
    
  • That's my code. I guess line 58 is the issue: if (many_Rects[i].overlaps(many_Rects[j])

  • looks ok to me.

    what is the issue?

  • Sorry, I was using Sublime as my text editor and it was not building properly. Yes it works. Thanks very much for those tips, Chrisir (and koogs) . Much obliged :)

  • edited February 27

    Sorry to bother you guys again.

    Turning the screen white when two lines overlapped, (line 60 in code above), was just a test. My ultimate goal here was sound related.

    I have a very long sample in the buffer which is mapped to the width of the screen. My desire is that, when any two lines intersect, the sample will trigger from that point in the buffer where they collide ie. if two lines collide in the far left of the screen the sound will trigger somewhere around the beginning of the sample and vice versa.

    Sound triggers fine, but I am having two issues:

    1. When the lines intersect, the sample is triggered continually in accordance with frame rate. I want it to trigger only once per intersection ie. the sound triggers on entry and not continually re-cueing for the duration that two lines overlap.

    2. Despite my best efforts I am unable to get the sample to trigger at the point(s) of contact between the arrays of lines.

    for (int i=0; i<many_Rects.length-1; i++) { for(int j=i+1; j<many_Rects.length; j++) { if (many_Rects[i].overlaps(many_Rects[j])) { println("OVERLAP"); int position = int(map( I_dont_know_What_To_Put_Here, 0, width, 0, groove.length() ) ); groove.cue( position ); } } }

    Could I be a little cheeky and ask for some tips here?

    Thank you!

  • For the first issue:

    You could implement a variable „overlapped“ that initializes to false. If an overlap occurs set the variable to true. Else set it to false.

  • Answer ✓

    When your song is written from left to right and you have multiple rects moving up and down: the rects are colliding vertically in one column.

    How many columns do we have from left to right? 100? How many rects are moving in each column, 2?

    You need for loop over the columns and then use the nested for loop checking each rect in the current column against the others in that column.

    Map: map(columnX or map(rectX....

  • Thanks for your help, Chrisir. Sorry for the delay. I am bouncing between forums for various language I have to learn this semester. did not realise I had not replied :)

Sign In or Register to comment.