同樣是 50 行程式碼,為什麼做出來的東西像藝術品?
先玩再說
想像一張圖:
800×800 像素的畫布上,幾百個小粒子在安靜地流動。它們不是往同一個方向走,而是每一個粒子都「感覺」到一種無形的力場——那個力場由一條數學公式決定,但做出來的結果,看起來像水、像雲、像呼吸。
這就是今天要做的東西。
別人做出來像藝術品,你做出來像數學作業
p5.js 有兩個關鍵:random() 和 noise()。
random() 做出來的像這樣:
▲▼▲▼▲▼▲▼ 雜亂,沒有方向
noise() 做出來的像這樣:
∿∿∿∿∿∿∿∿ 平滑,連續,有機
差別在於:noise() 不是真的隨機。它是「模擬大自然」的隨機。
50 行代碼裡藏了什麼?
核心概念只有三個:
1. 流場(Vector Field)
每一個像素點都有一個「方向」。這個方向由 noise(x, y) 決定。
let angle = noise(x * scale, y * scale) * TWO_PI * 4;
2. 粒子(Particles)
幾百個小粒子在流場裡移動。粒子不是往一個方向走,而是跟著「當下的流向」前進。
let velocity = p5.Vector.fromAngle(angle);
particle.pos.add(velocity);
3. 疊加(Accumulation)
每一個粒子的軌跡都留下痕跡。時間久了,整張圖就變成了「無數微小選擇的總結果」。
這就是為什麼看起來像藝術品——因為背後沒有人在控制結果,只有規則,沒有設計師。
怎麼讓它更好看?
參數設定是關鍵:
| 參數 | 效果 |
|---|---|
noiseScale |
越小 = 流場越平滑;越大 = 越破碎 |
strokeWeight(0.5) |
線條越細,越像水墨 |
| 背景疊加 | 每幀用半透明黑色覆蓋,產生拖尾效果 |
日式美學的秘密在於:留白。不要把整張圖填滿。
動手做
完整代碼(大約 50 行,不含空行):
let particles = [];
const NUM = 500;
let noiseScale = 0.02;
function setup() {
createCanvas(800, 800);
background(253, 250, 245);
for (let i = 0; i < NUM; i++) {
particles.push(new Particle());
}
}
function draw() {
background(253, 250, 245, 5); // 疊加拖尾
for (let p of particles) {
p.follow();
p.update();
p.edges();
p.show();
}
}
class Particle {
constructor() {
this.pos = createVector(random(width), random(height));
this.vel = createVector(0, 0);
this.maxSpeed = 2;
}
follow() {
let angle = noise(
this.pos.x * noiseScale,
this.pos.y * noiseScale,
frameCount * 0.005
) * TWO_PI * 4;
this.vel.x = cos(angle) * this.maxSpeed;
this.vel.y = sin(angle) * this.maxSpeed;
}
update() {
this.pos.add(this.vel);
}
edges() {
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.y > height) this.pos.y = 0;
if (this.pos.y < 0) this.pos.y = height;
}
show() {
stroke(30, 30, 30, 10);
strokeWeight(0.5);
point(this.pos.x, this.pos.y);
}
}
結語
藝術品和垃圾之間,往往只差一個參數。
但更準確地說,是差一個「讓系統自己說話」的決心。
你控制規則,不控制結果。
這就是 Generative Art 的核心。
標籤:p5js, generativeart, arduino, diy


