connect/disconnect logic/illogic
in
Programming Questions
•
1 year ago
Hi
I working on blobs, moving them around and connecting them in pairs. I've given the Blob class a Boolean isConnected which I set if the blob is connected to another blob, and have an array called connections which stores the array index of the blob's pair or -1 if it's not connected.
I have pared down my code to the test version below where the blobs are joined by a fading line (a la nodeGarden).
There are two errors (that I've spotted), which may or may not be symptoms of the same thing:
• sometimes a blob connects to more than one other blob
• sometimes the blob doesn't return to its unconnected ("I'm free") state. If I leave the program running for some time (> hour) gradually all the blobs disappear, in roughly reverse array order.
I would appreciate help untangling my illogic!
Thanks
- Blob[] blobs;
- int numBlobs = 11;
- Boolean showOutlines = false;
- int[] connections;
- float someMultiplier = 2.3;
- void setup()
- {
- size(800, 800);
- smooth();
- blobs = new Blob[numBlobs];
- connections = new int[numBlobs];
- for (int b = 0; b < numBlobs; b++)
- {
- PVector position = new PVector(random(width), random(height));
- PVector velocity = new PVector(random(-2, 2), random(-2, 2));
- color fillColour = color(random(150, 250), random(150, 250), random(150, 250));
- float fillAlpha = 96;
- //for testing
- float radius = map(b, 0, numBlobs, 20, 80);
- // float radius = random(20, 70);
- blobs[b] = new Blob(position, velocity, radius, fillColour, fillAlpha);
- connections[b] = -1;
- }
- }
- void draw()
- {
- background(255);
- for (int b = 0; b < numBlobs; b++)
- {
- blobs[b].update();
- blobs[b].checkEdges();
- if (showOutlines) blobs[b].showLines();
- if (!blobs[b].isConnected) blobs[b].display();
- }
- for (int b = 0; b < numBlobs - 1; b++)
- {
- Blob thisBlob = blobs[b];
- //if I comment out the second of these conditions
- //the blobs seem more likely to join to more than one other blob
- if ((thisBlob.isConnected) && (b < connections[b]))
- {
- //do connected stuff
- Blob otherBlob = blobs[connections[b]];
- //distance between centres
- float distance = dist(thisBlob.pos.x, thisBlob.pos.y, otherBlob.pos.x, otherBlob.pos.y);
- //distance between nearest points on circumferences
- distance -= (thisBlob.radius + otherBlob.radius);
- if (distance < (thisBlob.radius + otherBlob.radius) * someMultiplier)
- {
- if(distance < 0)
- {
- thisBlob.display();
- otherBlob.display();
- }
- else
- {
- PVector midPoint = new PVector();
- float dx = otherBlob.pos.x - thisBlob.pos.x;
- float dy = otherBlob.pos.y - thisBlob.pos.y;
- float angle = atan2(dy, dx);
- midPoint.x = thisBlob.pos.x + (thisBlob.radius + distance / 2) * cos(angle);
- midPoint.y = thisBlob.pos.y + (thisBlob.radius + distance / 2) * sin(angle);
- float bdist = dist(thisBlob.pos.x, thisBlob.pos.y, midPoint.x, midPoint.y);
- float otherdist = dist(otherBlob.pos.x, otherBlob.pos.y, midPoint.x, midPoint.y);
- if ((bdist > thisBlob.radius) && (otherdist > otherBlob.radius))
- {
- doNodeGarden(thisBlob, otherBlob, midPoint, distance);
- }
- }
- }
- else //disconnect
- {
- thisBlob.isConnected = false;
- otherBlob.isConnected = false;
- connections[connections[b]] = -1;
- connections[b] = -1;
- thisBlob.colour = thisBlob.startColour;
- otherBlob.colour = otherBlob.startColour;
- thisBlob.alfa = 96;
- otherBlob.alfa = 96;
- }
- }
- else //see if there's a blob near enough to connect to
- {
- for (int c = b + 1; c < numBlobs; c++)
- {
- if (connections[c] == -1)//!blobs[c].isConnected)
- {
- Blob otherBlob = blobs[c];
- float diffBetweenRadii = abs(thisBlob.radius - otherBlob.radius);
- if (dist(thisBlob.pos.x, thisBlob.pos.y, otherBlob.pos.x, otherBlob.pos.y) <= diffBetweenRadii)
- {
- thisBlob.isConnected = true;
- otherBlob.isConnected = true;
- connections[b] = c;
- connections[c] = b;
- }
- }
- }
- }
- }
- }
- //this is a testing display function
- void doNodeGarden(Blob b0, Blob b1, PVector mid, float distance)
- {
- float distRange = (b0.radius + b1.radius) * someMultiplier;
- float lineAlfa = map(distance, 0, distRange, 96, 16);
- b0.nodeGarden(mid, lineAlfa);
- b1.nodeGarden(mid, lineAlfa);
- }
- void keyPressed()
- {
- if (keyCode == 'L' || keyCode == 'l') showOutlines = !showOutlines;
- }
- void mousePressed()
- {
- for (int b = 0; b < numBlobs; b++)
- {
- if (dist(mouseX, mouseY, blobs[b].pos.x, blobs[b].pos.y) < blobs[b].radius)
- {
- println(b + " connected to " + connections[b]);
- }
- }
- }
and the Blob class
- class Blob
- {
- PVector pos;
- PVector vel;
- float startRadius, radius;
- color startColour, colour;
- float alfa;
- Boolean isConnected = false;
- Blob(PVector pos, PVector vel, float startRadius, color startColour, float alfa)
- {
- this.pos = pos;
- this.vel = vel;
- this.startRadius = startRadius;
- this.startColour = startColour;
- this.radius = startRadius;
- this.colour = startColour;
- this.alfa = alfa;
- }
- void display()
- {
- noStroke();
- fill(colour, alfa);
- ellipse(pos.x, pos.y, radius*2, radius*2);
- }
- void nodeGarden(PVector midPoint, float lineAlfa)
- {
- stroke(colour, lineAlfa);
- strokeWeight(5);
- line(pos.x, pos.y, midPoint.x, midPoint.y);
- noStroke();
- fill(colour, lineAlfa);
- ellipse(pos.x, pos.y, radius*2, radius*2);
- }
- void update()
- {
- pos.x += vel.x;
- pos.y += vel.y;
- }
- void showLines()
- {
- noFill();
- stroke(colour);
- ellipse(pos.x, pos.y, radius*2, radius*2);
- }
- void checkEdges()
- {
- if (pos.x + radius >= width)
- {
- pos.x = width - radius;
- vel.x *= -1;
- }
- if (pos.x <= radius)
- {
- pos.x = radius;
- vel.x *= -1;
- }
- if (pos.y + radius >= height)
- {
- pos.y = height - radius;
- vel.y *= -1;
- }
- if (pos.y <= radius)
- {
- pos.y = radius;
- vel.y *= -1;
- }
- }
- }
1