Connect

Basil.js, chance, repeat, Law of Proximity, Law of Connected Elements
Fabian Morón Zirfas
// @includepath "~/Documents/;%USERPROFILE%Documents"; // eslint-disable-line
// @include "basiljs/bundle/basil.js";// eslint-disable-line
// This sketch connects ovals by chance.
// if the distance is lower then a set number
// it draws a line from one circle to another
var pw = 500; // for easier handling
var ph = 500; // for easier handling
var num = 200; // the number of circles to draw
var diam = 5; // their diameter
var maxdist = diam * 3; // the max distance
var coordinates = []; // to create some coordinates to work with
var ellipses = []; // this will hold all ellipses for checking their distance to one another
function draw() {
  b.clear(b.doc()); // clear the current document
  // b.units(b.MM); // we want to print. use MM instead of default pixels
  b.ellipseMode(b.CENTER); // draw from the center
  var doc = b.doc(); // a reference to the current document
  // set some preferneces of the document for better handling
  b.size(pw, ph); // set the page size
  doc.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN; // upper left corner
  // ----------
  // main code goes here

  b.fill(255); // just styling
  b.stroke(128); // just styling
  // we create a random set of coordinates
  for(var i = 0; i < num; i++) {
    var x = b.random(0, b.width);
    var y = b.random(0, b.height);
    coordinates.push({xPos:x, yPos:y});
  }

  // now we create ellipses/ovals at these coords
  for(var j = 0; j < coordinates.length; j++) {
    var ell = b.ellipse(coordinates[j].xPos, coordinates[j].yPos, diam, diam);
    ellipses.push(ell);
  }
  // we loop all the ellipses we have and check their position
  // against all the others
  for(var k = ellipses.length - 1; k >= 0; k--) {
    for(var l = ellipses.length - 1; l >= 0; l--) {
      // exclude itself
      if(k !== l) {
        // it is not itself we get the x/y coordiante from the ovals
        // we could also use b.itemPosition(item)
        // but don't :-)
        // in InDesign every object has its geometricBounds
        // this is stored in an array of 4 coordinates
        // y1 and x1 upper left corner
        // y2 and x2 lower right corner
        // [y1, x1, y2, x2]
        // be aware that y comes before x !
        //
        var xk = ellipses[k].geometricBounds[1] + diam / 2;
        var yk = ellipses[k].geometricBounds[0] + diam / 2;
        var xl = ellipses[l].geometricBounds[1] + diam / 2;
        var yl = ellipses[l].geometricBounds[0] + diam / 2;
        // check the distance
        if(b.dist(xk, yk, xl, yl) < maxdist) {
          // houston we are in range
          var line = b.line(xk, yk, xl, yl); // draw a line
          line.sendToBack(); // and send it to the back
        }
      }
    }
    // this is important
    // we remove each checked object from our array
    // if we don't do that we will have double lines
    ellipses.pop(); // removes the last item. Thats why we loop from the end of the array
  }
  // if we don't send each line to the back while creation, we can do this for all at once
  // doc.pages[0].graphicLines.everyItem().sendToBack();
  b.fill(0); // more styling
  var bg = b.rect(0, 0, pw, ph); // draw a background
  bg.sendToBack(); // and send it to the back as well
  // ----------
  var fname = File($.fileName).parent.fsName + '/' + ($.fileName.split('/')[$.fileName.split('/').length - 1]).split('.')[0] + '.indd';
 // b.println(fname);
  doc.save(fname, false, 'basil', true);
  b.savePNG('out.png');
}
b.go();