How to simulate the magnetism in water dropplets

My end goal is to achieve something like what is in the JetBrains website, basically I want to draw the red parts in this image:

I have tried to add a threshold and draw the red part when the pixel’s distance is in between two or more circles + the threshold, but that just gave me almond shapes in between the circles.
I also tried drawing gradients and using the threshold filter witch kind of worked, but gave me a square-like junctions between the circles and not the nice parabola shapes that’s in the image.

Thank you in advance for your help!!!

1 Like

you might want to check out this page though that is a little complicated. another way to do it is with blending such as this

int ballCount;
Ball[] balls;
PImage radialGradient;
PGraphics mCanvas;
void setup() {
  size(640, 480);
  noStroke();
  ballCount = 10;
  balls = new Ball[ballCount];
  for(int i = 0; i < ballCount; i++) {
    float radius = random(32, 64);
    balls[i] = new Ball(random(radius * 2, width - radius * 2), random(radius * 2, height - radius * 2), radius);
    PVector vel = PVector.random2D();
    balls[i].addForce(vel.x * 10, vel.y * 10);
  }
  radialGradient = loadImage("radialGradient1.png");
  
  mCanvas = createGraphics(width, height);
}

void draw() {
  background(51);
  mCanvas.beginDraw();
  mCanvas.clear();
  mCanvas.endDraw();
  for(int i = 0; i < ballCount; i++) {
    balls[i].update();
    balls[i].present();
  }

  mCanvas.loadPixels();
  int threshold = 210;
  for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
      int xy = x + y * width;
      float a = alpha(mCanvas.pixels[xy]);
      if(a < threshold) {
        a = (a / 6);
        if(a > threshold / 4) {
          a = 0;
        }
        mCanvas.pixels[xy] = color(red(mCanvas.pixels[xy]), green(mCanvas.pixels[xy]), blue(mCanvas.pixels[xy]), a);
      }
    }
  }
  mCanvas.updatePixels();
  image(mCanvas, 0, 0);
}

class Ball
{
  PVector pos, vel, acc;
  float radius;
  color col;
  Ball(float x, float y, float radius) {
    this.pos = new PVector(x, y);
    this.vel = new PVector();
    this.acc = new PVector();
    this.radius = radius;
    this.col = color(random(50, 255), 0, random(50, 255));
  }
  void addForce(float x, float y) {
    acc.x += x;
    acc.y += y;
  }
  void update() {
    vel.add(acc);
    acc.mult(0);
    
    if(pos.x < -radius / 2 || pos.x > width - radius * 1.5)
      vel.x = -vel.x;
    if(pos.y < -radius / 2 || pos.y > height - radius * 1.5)
      vel.y = -vel.y;
    
    pos.add(vel);
  }
  void present() {
    mCanvas.beginDraw();
    mCanvas.tint(col);
    mCanvas.image(radialGradient, pos.x, pos.y, radius * 2, radius * 2);
    mCanvas.endDraw();
  }
}

which looks something like

gradial

edit: this is the image i used for the code above (prob can’t see it on this background but it’s there. it’s just a radial gradient.
radialGradient1

3 Likes