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.
show code
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;
}
}
Cómo funciona
- arrastre nodos para reconfigurar la red
- teclas a y z modifican el alcance de cada nodo
- botón derecho sobre el nodo lo enciende o apaga
- tecla i sirve para invertir encendido/apagado de todos los nodos
- x regenera la distribución de nodos
Agregar un comentario