📝 Codi explicat línia a línia

/*
                ====================================================
                PRÀCTICA 14
                GRAVETAT I ÒRBITES GENERATIVES
                ====================================================

                REFERENTS

                - Casey Reas
                - Robert Hodgin
                - Simulacions físiques en art generatiu

                OBJECTIU

                Aprendre a utilitzar:

                - forces
                - acceleració
                - atracció gravitatòria
                - vectors de moviment
                - simulació física simple

                Fins ara hem mogut partícules amb
                velocitat constant o amb camps de flux.

                Ara simularem una força fonamental
                de la natura: la gravetat.

                Cada partícula serà atreta cap a un
                punt central (el Sol). Depenent de la
                seva velocitat inicial, entrarà en
                òrbita, caurà o s'escaparà.

                Així creem un petit sistema planetari
                generatiu.
                */


                /*
                Array per emmagatzemar tots els cossos.
                */
                let cossos = [];


                function setup() {

                createCanvas(900, 600);

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

                /*
                Creem uns quants cossos inicials
                amb posicions i velocitats aleatòries.
                */
                for (let i = 0; i < 15; i++) {
                    cossos.push(new Cos(
                        random(width),   // posició X
                        random(height),  // posició Y
                        random(-3, 3),   // velocitat X inicial
                        random(-2, 2)    // velocitat Y inicial
                    ));
                }

                }


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

                function draw() {

                /*
                Fons amb transparència per deixar
                un rastre suau del moviment orbital.
                */
                background(10, 10, 30, 25);

                /*
                Dibuixem el "Sol" al centre.
                */
                noStroke();
                fill(255, 220, 50, 200);
                circle(width / 2, height / 2, 30);

                /*
                Per a cada cos, calculem l'atracció
                cap al Sol i actualitzem el moviment.
                */
                for (let c of cossos) {
                    /*
                    Calculem la força d'atracció
                    cap al centre de la pantalla.
                    */
                    c.aplicarGravetat(
                        width / 2,  // X de l'atractor
                        height / 2, // Y de l'atractor
                        0.4         // intensitat de la gravetat
                    );

                    c.actualitzar();
                    c.dibuixar();
                }

                }


                /*
                ====================================================
                CLASSE COS
                ====================================================

                Representa un objecte que es mou
                sota l'efecte d'una força d'atracció.

                Té:

                - posició (x, y)
                - velocitat (vx, vy)
                - acceleració (ax, ay)
                - color
                - mida
                */

                class Cos {

                constructor(x, y, vx, vy) {

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

                    this.vx = vx;
                    this.vy = vy;

                    // Acceleració inicial zero
                    this.ax = 0;
                    this.ay = 0;

                    // Color aleatori per a cada cos
                    this.color = color(
                        random(100, 255),
                        random(100, 255),
                        random(200, 255),
                        180
                    );

                    this.mida = random(4, 10);

                }


                /*
                --------------------------------------------------
                APLICAR GRAVETAT
                --------------------------------------------------

                Calcula l'acceleració cap a un punt
                (atractorX, atractorY) amb una
                intensitat donada.

                Com més a prop, més atracció.
                */

                aplicarGravetat(atractorX, atractorY, intensitat) {

                    /*
                    Vector direcció:
                    diferència entre l'atractor i
                    la posició actual.
                    */
                    let dx = atractorX - this.x;
                    let dy = atractorY - this.y;

                    /*
                    Distància entre el cos i l'atractor.
                    Afegim un valor petit per evitar
                    divisions per zero.
                    */
                    let distancia = sqrt(
                        dx * dx + dy * dy
                    ) + 0.1;

                    /*
                    Força proporcional a la intensitat
                    i inversament proporcional a la
                    distància (simplificació de la
                    llei de la gravetat).
                    */
                    let força = intensitat / distancia;

                    /*
                    Acceleració = força en cada eix.
                    */
                    this.ax = (dx / distancia) * força;
                    this.ay = (dy / distancia) * força;

                }


                /*
                --------------------------------------------------
                ACTUALITZAR MOVIMENT
                --------------------------------------------------
                */

                actualitzar() {

                    // La velocitat canvia amb l'acceleració
                    this.vx += this.ax;
                    this.vy += this.ay;

                    // La posició canvia amb la velocitat
                    this.x += this.vx;
                    this.y += this.vy;

                    /*
                    Si el cos surt dels límits,
                    el fem reaparèixer al costat contrari
                    (efecte wrap).
                    */
                    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 COS
                --------------------------------------------------
                */

                dibuixar() {

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

                }

                }


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

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

                function mousePressed() {

                cossos.push(new Cos(
                    mouseX,
                    mouseY,
                    random(-4, 4),
                    random(-4, 4)
                ));

                }


                /*
                ====================================================
                QUÈ ÉS UNA FORÇA?
                ====================================================

                En física, una força provoca
                una acceleració (canvi de velocitat).

                En el nostre codi:

                - Calculem la direcció cap al Sol.
                - Apliquem una acceleració en
                  aquesta direcció.
                - La velocitat canvia.
                - La posició canvia.

                Sense acceleració, el moviment
                és recte i uniforme. Amb gravetat,
                apareixen corbes i òrbites.
                */


                /*
                ====================================================
                PER QUÈ DEIXEM RASTRE?
                ====================================================

                background(10,10,30,25);

                L'últim valor (25) és l'opacitat.
                Com que és baixa, el fons anterior
                no s'esborra completament.

                Això crea un efecte de "rastre"
                que mostra les trajectòries orbitals.
                */


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

                Canvia la intensitat de la gravetat
                (0.4) per 0.1 o per 1.5.
                Com afecta les òrbites?
                */


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

                Canvia el nombre inicial de cossos
                (15) per 5 o per 50.
                Observa com canvia la densitat visual.
                */


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

                En lloc d'un sol atractor al centre,
                crea dos atractors (per exemple,
                a l'esquerra i a la dreta).
                Com es compliquen les trajectòries?
                */


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

                Substitueix l'atractor fix pel ratolí:

                aplicarGravetat(mouseX, mouseY, 0.4);

                Ara les partícules segueixen
                el cursor.
                */


                /*
                ====================================================
                REPTE 1 · SISTEMA SOLAR MINIMALISTA
                ====================================================
                Dissenya un sistema planetari:
                - Sol central gran
                - 3-4 planetes amb òrbites circulars
                - colors freds per als planetes
                */


                /*
                ====================================================
                REPTE 2 · PLUJA D'ESTRELLES
                ====================================================
                Partícules petites, molta velocitat
                inicial, gravetat baixa.
                Colors càlids. Fons negre.
                */


                /*
                ====================================================
                REPTE 3 · DANSA CÒSMICA
                ====================================================
                Dos atractors mòbils (per exemple,
                un a l'esquerra i un que orbita).
                Colors complementaris.
                */


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

                Afegeix una segona força:
                repulsió entre els cossos.

                Quan dos cossos estan a prop,
                s'empenyen. Això genera
                comportaments molt complexos
                (flocking, eixams).
                */


                /*
                ====================================================
                NETEJAR PANTALLA
                ====================================================

                Prem la tecla 'C' per esborrar
                tots els cossos i començar de nou.
                */

                function keyPressed() {

                if (key === 'c' || key === 'C') {
                    cossos = [];
                    background(10, 10, 30);
                }

                }


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

                1. Què passaria sense la força de
                   gravetat? Com es mourrien els cossos?

                2. Per què alguns cossos orbiten
                   i d'altres cauen directament?

                3. Com canvia el comportament del
                   sistema amb diferents intensitats?

                4. Aquest sistema recorda algun
                   fenomen natural real?

                5. On més podries aplicar forces
                   en una obra generativa?
                */


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

                Crea un univers generatiu.

                CONDICIONS:

                ✓ Mínim 20 cossos
                ✓ Ús d'acceleració i forces
                ✓ Atractor interactiu o múltiple
                ✓ Efecte de rastre visual
                ✓ Interacció amb l'usuari

                Guarda captures en moments diferents
                per veure l'evolució del sistema.

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

                IDEA CLAU

                Afegir forces a les nostres
                partícules obre un ventall enorme
                de possibilitats visuals.

                La física es converteix en
                una eina artística.

                Les mateixes equacions que descriuen
                el moviment dels planetes poden
                generar obres d'art digital.

                Aquesta és la bellesa del
                creative coding: unir ciència,
                natura i art.

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

🎨 Resultat renderitzat (clic per afegir cossos, tecla C per netejar)