Mesh Network

Esta ilustración fue generada para explicar el funcionamiento de una red enmallada (mesh network) en cuanto figura de distribución y conexión entre nodos. La aplicación práctica de esta red fue discutida en el post anterior, describiendo la necesidad de una arquitectura de red resistente a cataclismos como el pasado terremoto y donde todos los nodos aportan, yendo más allá de ser meros clientes. Una red pública es aquella donde cada participante expande su alcance por el simple hecho de pertenecer.

[p5js code canvas] void setup() { size(500, 500); NODES = new ArrayList(); for (int i = 0; i < numNodes; i++) { Node n = new Node(random(margin, width-margin), random(margin, height-margin)); if (random(1) >0.25) { n.device = true; } else { n.r = 1.5; } NODES.add(n); } newNode = false; smooth(); } void draw() { background(255); if (newNode) { NODES.add(current); newNode = false; } for (int i = 0; i < NODES.size (); i++) { Node n = (Node)NODES.get(i); n.calc(); n.renderLinks(); } for (int i = 0; i < NODES.size (); i++) { Node n = (Node)NODES.get(i); n.calc(); if (n.device) { n.renderDevice(); } else { n.renderNode(); } } } class Node { int id; // the ID of this node float x, y; // position float r; // radius float signal; // ammount of signal boolean on; // is it on? boolean over; // is the mouse over this one? ArrayList nodes; // list of nodes that are connected to this one boolean device = false; float angle, step; Node(float X, float Y) { count++; id = count; x = X; y = Y; signal = 0; on = true; nodes = new ArrayList(); r = 7.0; angle = random(TWO_PI); step = random(1); } void renderNode() { if (over) { noFill(); stroke(linkColor); strokeWeight(.50); ellipse(x, y, nodeScope, nodeScope); fill(nodeFillColor); stroke(nodeStrokeColor); } else { fill(nodeFillColor, 150); stroke(nodeStrokeColor, 50); } if (on) { strokeWeight(3); } else { strokeWeight(0.5); } ellipse(x, y, r, r); } void renderDevice() { move(); if (over) { noFill(); stroke(linkColor); strokeWeight(.5); ellipse(x, y, nodeScope, nodeScope); fill(deviceFillColor); stroke(deviceStrokeColor); } else { fill(deviceFillColor, 150); stroke(deviceStrokeColor, 150); } if (on) { strokeWeight(1); } else { noStroke(); } ellipse(x, y, r, r); } void renderLinks() { if (on) { stroke(linkColor, 100); for (int i = 0; i < nodes.size (); i++) { Node n = (Node)nodes.get(i); float d = dist(x, y, n.x, n.y); float sw = map(d, r, nodeScope, 5, 0.1); sw = constrain(sw, 0.01, 20); strokeWeight(sw); line(x, y, n.x, n.y); } } } void calc() { nodes.clear(); for (int i = 0; i < NODES.size (); i++) { Node n = (Node)NODES.get(i); if (id != n.id) { float nodeDist = dist(x, y, n.x, n.y); if (nodeDist <= nodeScope && n.on) { nodes.add(n); } } } } void move() { noiseSeed(id); angle += (noise((float)millis()/100.0) - .5) HALF_PI; x += cos(angle)step; y += sin(angle)step; } } boolean OVER; ArrayList NODES; int numNodes = 50; int count = 0; float margin = 100; float nodeScope = 60; boolean newNode; Node current; color nodeFillColor = #F06E1D; color nodeStrokeColor = #8E3E0B; color linkColor = color(86, 115, 124, 80); color deviceFillColor = #1FCCFF; color deviceStrokeColor = #02A8D8; void keyPressed() { if (key == ‘a’) { nodeScope += 5; println(“node scope = “+nodeScope); } if (key == ‘z’) { nodeScope -= 5; println(“node scope = “+nodeScope); } if (key == ‘ ‘) { for (int i = 0; i < NODES.size (); i++) { Node n = (Node)NODES.get(i); n.on = !n.on; } } if (key == ‘x’) { setup(); } nodeScope = constrain(nodeScope, 5, width); } void mouseMoved() { float d; for (int i = 0; i < NODES.size (); i++) { Node n = (Node)NODES.get(i); d = dist(mouseX, mouseY, n.x, n.y); if (n.r*1.5 >= d) { OVER = true; n.over = true; current = n; } else { OVER = false; n.over = false; } } } void mouseDragged() { if (OVER) { if (current.over) { current.x = mouseX; current.y = mouseY; } } } void mouseReleased() { if (current.over && mouseButton==RIGHT) { current.on = !current.on; } } [/p5js]

Cómo funciona