📝 Codi explicat línia a línia

/*
                ====================================================
                PRÀCTICA 15
                XARXES VIVES I CONSTEL·LACIONS GENERATIVES
                ====================================================

                REFERENTS

                - Manfred Mohr
                - Marius Watz
                - Art de xarxes i grafs generatius

                OBJECTIU

                Aprendre a utilitzar:

                - connexions entre objectes
                - grafs i xarxes
                - distància entre punts
                - comportament emergent
                - estructures relacionals

                Fins ara hem creat sistemes amb
                partícules independents o amb forces
                globals. Ara connectarem les partícules
                entre si.

                Quan dos nodes estan prou a prop,
                dibuixarem una línia entre ells.

                El resultat és una xarxa viva,
                una constel·lació artificial que
                canvia i respira.

                Aquesta tècnica s'utilitza en
                visualització de dades, art generatiu
                i instal·lacions interactives.
                */


                /*
                Array de nodes (partícules).
                */
                let nodes = [];


                function setup() {

                createCanvas(900, 600);

                // Vinculem el canvas al contenidor HTML
                let cnv = createCanvas(900, 600);
                cnv.parent("canvas-container");

                /*
                Creem uns quants nodes inicials
                amb posicions aleatòries.
                */
                for (let i = 0; i < 30; i++) {
                    nodes.push(new Node(
                        random(width),
                        random(height)
                    ));
                }

                }


                /*
                ====================================================
                ANIMACIÓ PRINCIPAL
                ====================================================
                */

                function draw() {

                background(15, 15, 30, 30);

                /*
                Actualitzem tots els nodes.
                */
                for (let n of nodes) {
                    n.actualitzar();
                }

                /*
                Dibuixem les connexions entre nodes
                propers. Això es fa abans de dibuixar
                els nodes perquè les línies quedin
                darrere dels cercles.
                */
                dibuixarConnexions();

                /*
                Dibuixem els nodes a sobre.
                */
                for (let n of nodes) {
                    n.dibuixar();
                }

                }


                /*
                ====================================================
                FUNCIÓ DIBUIXAR CONNEXIONS
                ====================================================

                Compara cada parell de nodes.
                Si la distància entre ells és
                menor que un llindar, dibuixa
                una línia.

                El color i el gruix de la línia
                depenen de la distància.
                */

                function dibuixarConnexions() {

                let llindar = 120; // distància màxima per connectar

                /*
                Doble bucle per comparar tots
                els parells sense repetir.
                */
                for (let i = 0; i < nodes.length; i++) {
                    for (let j = i + 1; j < nodes.length; j++) {

                    let a = nodes[i];
                    let b = nodes[j];

                    /*
                    Calculem la distància entre
                    els dos nodes.
                    */
                    let dx = a.x - b.x;
                    let dy = a.y - b.y;
                    let distancia = sqrt(dx * dx + dy * dy);

                    /*
                    Si estan prou a prop,
                    dibuixem una línia.
                    */
                    if (distancia < llindar) {

                        /*
                        Opacitat: més opaca com més
                        a prop estiguin.
                        */
                        let opacitat = map(
                            distancia,
                            0,
                            llindar,
                            200,
                            10
                        );

                        /*
                        Gruix: més fi com més lluny.
                        */
                        let gruix = map(
                            distancia,
                            0,
                            llindar,
                            2.5,
                            0.3
                        );

                        strokeWeight(gruix);

                        /*
                        Color: tons freds amb
                        variacions suaus.
                        */
                        stroke(
                            120 + (a.x / width) * 80,
                            180 + (b.y / height) * 70,
                            255,
                            opacitat
                        );

                        line(a.x, a.y, b.x, b.y);

                    }
                    }
                }

                }


                /*
                ====================================================
                CLASSE NODE
                ====================================================

                Cada node és un punt que es mou
                suaument amb soroll Perlin.

                Té:
                - posició (x, y)
                - color
                - mida
                */

                class Node {

                constructor(x, y) {

                    this.x = x;
                    this.y = y;

                    /*
                    Offset únic per al soroll.
                    Cada node té el seu propi
                    "temps" per evitar que tots
                    es moguin igual.
                    */
                    this.offsetX = random(1000);
                    this.offsetY = random(1000);

                    /*
                    Increment del soroll:
                    velocitat del moviment.
                    */
                    this.inc = random(0.003, 0.008);

                    /*
                    Color del node.
                    */
                    this.color = color(
                        random(150, 255),
                        random(150, 255),
                        255,
                        220
                    );

                    this.mida = random(4, 10);

                }


                actualitzar() {

                    /*
                    Utilitzem noise() per crear
                    un moviment orgànic.
                    */
                    let movimentX = noise(
                        this.offsetX
                    ) * 2 - 1;

                    let movimentY = noise(
                        this.offsetY
                    ) * 2 - 1;

                    this.x += movimentX;
                    this.y += movimentY;

                    /*
                    Incrementem els offsets per
                    al següent fotograma.
                    */
                    this.offsetX += this.inc;
                    this.offsetY += this.inc;

                    /*
                    Marges: reaparició suau.
                    */
                    if (this.x < 0) this.x = width;
                    if (this.x > width) this.x = 0;
                    if (this.y < 0) this.y = height;
                    if (this.y > height) this.y = 0;

                }


                dibuixar() {

                    noStroke();
                    fill(this.color);
                    circle(this.x, this.y, this.mida);

                }

                }


                /*
                ====================================================
                INTERACCIÓ
                ====================================================

                Cada clic afegeix un node nou
                a la posició del ratolí.
                */

                function mousePressed() {

                nodes.push(new Node(mouseX, mouseY));

                }


                /*
                ====================================================
                REINICIAR
                ====================================================

                Prem la tecla 'R' per buidar
                la xarxa i començar de nou.
                */

                function keyPressed() {

                if (key === 'r' || key === 'R') {
                    nodes = [];
                    background(15, 15, 30);
                }

                }


                /*
                ====================================================
                QUÈ ÉS UN GRAF?
                ====================================================

                Un graf és un conjunt de nodes
                (vèrtexs) connectats per arestes
                (línies).

                En el nostre cas, les connexions
                no són fixes: canvien amb cada
                fotograma segons la distància.

                Això crea una estructura dinàmica
                i orgànica.
                */


                /*
                ====================================================
                PER QUÈ UN DOBLE BUCLE?
                ====================================================

                Per comprovar totes les parelles
                possibles de nodes sense repetir.

                Si tenim 5 nodes: A,B,C,D,E

                Comparem:
                A-B, A-C, A-D, A-E
                B-C, B-D, B-E
                C-D, C-E
                D-E

                En total: 5*4/2 = 10 parelles.
                */


                /*
                ====================================================
                QUÈ FA MAP()?
                ====================================================

                Converteix un valor d'un rang
                a un altre.

                map(distancia, 0, llindar, 200, 10)

                Quan distancia = 0 → opacitat = 200
                Quan distancia = llindar → opacitat = 10

                Valors intermedis: interpolació lineal.
                */


                /*
                ====================================================
                EXERCICI 1
                ====================================================

                Canvia el llindar (120) per 60 o 200.
                Com afecta la densitat de la xarxa?
                */


                /*
                ====================================================
                EXERCICI 2
                ====================================================

                Modifica el color de les línies.
                Prova tons càlids, verds o
                monocromàtics.
                */


                /*
                ====================================================
                EXERCICI 3
                ====================================================

                Fes que el llindar canviï amb el
                moviment del ratolí.

                let llindar = map(mouseX, 0, width, 20, 250);

                Mou el ratolí horitzontalment
                i observa com respira la xarxa.
                */


                /*
                ====================================================
                EXERCICI 4
                ====================================================

                Substitueix les línies per cercles
                o rectangles als punts mitjans.
                Com canvia l'estètica?
                */


                /*
                ====================================================
                REPTE 1 · CONSTEL·LACIÓ ESTÀTICA
                ====================================================
                Crea nodes fixos (sense moviment)
                i dibuixa connexions amb un llindar
                elevat. Inspiració: carta estel·lar.
                */


                /*
                ====================================================
                REPTE 2 · XARXA ORGÀNICA
                ====================================================
                Molts nodes (100+), moviment lent,
                colors suaus. Inspiració: teixit
                biològic, xarxes neuronals.
                */


                /*
                ====================================================
                REPTE 3 · ATRACCIÓ I REPULSIÓ
                ====================================================
                Afegeix una força d'atracció cap
                al ratolí i repulsió entre nodes
                molt propers. El sistema es
                comportarà com un fluid.
                */


                /*
                ====================================================
                REPTE AVANÇAT
                ====================================================

                Afegeix diferents tipus de nodes
                i connexions amb regles diferents:

                - Nodes "estel": connecten amb molts.
                - Nodes "planeta": connecten amb pocs.
                - Nodes "forat negre": atrauen els
                  nodes propers.

                La xarxa es converteix en un
                ecosistema complex.
                */


                /*
                ====================================================
                PREGUNTES DE REFLEXIÓ
                ====================================================

                1. Què és més important: els nodes
                   o les connexions entre ells?

                2. Com canvia la percepció de l'obra
                   amb diferents llindars?

                3. Aquesta tècnica podria servir per
                   visualitzar dades reals? Com?

                4. L'obra recorda alguna estructura
                   natural? Quina?

                5. Què passaria si cada node tingués
                   un llindar de connexió diferent?
                */


                /*
                ====================================================
                PROJECTE FINAL DE LA PRÀCTICA
                ====================================================

                Crea una instal·lació generativa
                basada en xarxes.

                CONDICIONS:

                ✓ Mínim 40 nodes
                ✓ Connexions dinàmiques
                ✓ Moviment orgànic amb noise()
                ✓ Interacció amb ratolí
                ✓ Colors harmoniosos

                Temes suggerits:

                - Constel·lació personal
                - Xarxa neuronal
                - Mapa de relacions
                - Teixit digital

                Guarda captures en diferents
                moments per veure l'evolució
                de la xarxa.

                ====================================================

                IDEA CLAU

                Les connexions són tan importants
                com els elements individuals.

                Una xarxa no es defineix només
                pels seus nodes, sinó per les
                relacions entre ells.

                En art generatiu, les regles
                de connexió poden crear patrons
                visuals molt rics i suggerents.

                Aquesta idea s'aplica a:

                - Visualització de dades
                - Simulació de xarxes socials
                - Models biològics
                - Disseny de patrons tèxtils

                ====================================================
                */

🎨 Resultat renderitzat (clic per afegir nodes, tecla R per reiniciar)