๐ŸŽ“ 3์ฃผ์ฐจ: ๋ฐ˜๋ณต๊ณผ ํŒจํ„ด (Iteration & Pattern)

BamgasiJMยท2025๋…„ 11์›” 5์ผ

p5.js Art

๋ชฉ๋ก ๋ณด๊ธฐ
13/66
post-thumbnail

์„  ๊ทธ๋ฆฌ๊ธฐ

function setup() {
  createCanvas(800, 400);
  background(23);
}

function draw() {
  for (let i = 20; i < width; i += 20) {
    stroke(255);
    line(i, 0, i, height); // (x1, y1, x2, y2) : ์œ„์—์„œ ์•„๋ž˜๋กœ ์ˆ˜์ง์„ 
  }
}
  • ์ด ์˜ˆ์ œ์—์„œ๋Š” draw ํ•จ์ˆ˜ ๋Œ€์‹  setup์— ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
  • draw๋Š” ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์‹คํ–‰๋˜๋ฏ€๋กœ, ๋ผ์ธ์„ ๊ณ„์† ๊ทธ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • x ์ขŒํ‘œ๋ฅผ 20๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ 20์”ฉ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ ๋ฐ˜๋ณต
    • i < 800 ์ด๋ฉด x๊ฐ€ 780๊นŒ์ง€ ๊ทธ๋ ค์ง€๊ณ , i <= 800 ์ด๋ฉด x๊ฐ€ 800๊นŒ์ง€ ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.
    • ์—ฌ๊ธฐ์„œ๋Š” 800์„ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋„๋ก < 800์œผ๋กœ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • line()๋Š” (x1, y1, x2, y2)๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์„ ์„ ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

๊ฒฉ์ž ํŒจํ„ด (Grid Pattern)

function setup() {
  createCanvas(800, 400);
  background(25);
  noFill(); 
  stroke(100, 200, 255); 
  strokeWeight(1);
}

function draw() {
  // ๊ฐ€๋กœ์„ ์„ ๊ทธ๋ฆฌ๋Š” ๋ฐ˜๋ณต๋ฌธ
  for (let y = 20; y < height; y += 40) {
    // ์„ธ๋กœ์„ ์„ ๊ทธ๋ฆฌ๋Š” ๋ฐ˜๋ณต๋ฌธ (๊ฐ€๋กœ์„  ์•ˆ์— ์žˆ์Œ)
    for (let x = 20; x < width; x += 40) {
      rect(x, y, 30, 30); // (x, y) ์œ„์น˜์— 30x30 ํฌ๊ธฐ์˜ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
    }
  }
}

์  ํŒจํ„ด (Dot Pattern)

function setup() {
  createCanvas(800, 400);
  noLoop();
  noStroke();
}

function draw() {
  background(25);
  let step = 20;
  // x += 1 : 1 ํ”ฝ์…€์”ฉ ์ด๋™ํ•˜๋ฉด์„œ ๊ทธ๋ฆผ
  // x += step : step์œผ๋กœ ์„ค์ •๋œ ์ˆ˜๋งŒํผ ์ด๋™ํ•˜๋ฉด์„œ ๊ทธ๋ฆผ
  for (let x = 0; x < width; x += step) {
    for (let y = 0; y < height; y += step) {
      let r = int(random(0, 20));
      let g = int(random(130, 180));
      let b = int(random(120, 150));

      fill(r, g, b);
      ellipse(x + step / 2, y + step / 2, step - 2);
    }
  }
}

๋ฐฉ์‚ฌํ˜• ํŒจํ„ด (Radial Symmetry)

function setup() {
  createCanvas(800, 400);
  colorMode(HSB, 360, 100, 100, 100);
}

function draw() {
  background(0, 0, 10);
  translate(width / 2, height / 2);

  let layers = 8;
  let petals = 16;

  for (let j = 0; j < layers; j++) {
    let radius = map(j, 0, layers, 40, 200);
    for (let i = 0; i < petals; i++) {
      push();
      rotate((TWO_PI * i) / petals);
      let hue = map(j, 0, layers, 150, 200);
      fill(hue, 80, 100, 80);
      noStroke();
      ellipse(radius, 0, 12, 12);
      pop();
    }
  }
}
  • colorMode(HSB)๋ฅผ ์‚ฌ์šฉํ•ด์„œ hue๊ฐ’๋งŒ 150~200 ์‚ฌ์ด๋กœ ๋ณ€ํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์ธ์ˆ˜์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์˜ ๋ฒ”์œ„๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • Hue: 0~360 (์ƒ‰์ƒ)
    • Saturation: 0~100 (์ฑ„๋„)
    • Brightness: 0~100 (๋ช…๋„)
    • Alpha: 0~100 (ํˆฌ๋ช…๋„)

๋‚˜์„ ํ˜• (Spriral)

function setup() {
  createCanvas(800, 400);
  angleMode(DEGREES);
  noLoop();
}

function draw() {
  background(25);
  translate(width / 2, height / 2);

  let n = 200;
  let baseRadius = 2;
  let angleStep = 10;

  for (let i = 0; i < n; i++) {
    let angle = i * angleStep;
    let radius = baseRadius + i * 1.8;
    let x = radius * cos(angle);
    let y = radius * sin(angle);

    // ์ƒ‰์ƒ: i ๊ฐ’์— ๋”ฐ๋ผ ๋ณ€ํ™”
    let brightness = map(i, 0, n, 50, 255);
    fill(brightness, 120, 200, 180);

    noStroke();
    ellipse(x, y, 15, 15);
  }
}

์œ„์•„๋ž˜ ์ง„๋™ํ•˜๋Š” ๊ณต

function setup() {
  createCanvas(800, 400);
  background(23, 23, 23);
  noStroke();
}

function draw() {
  // ๋งค ํ”„๋ ˆ๋งˆ๋‹ค ๋ฐฐ๊ฒฝ์„ ๋‹ค์‹œ ์น ํ•˜์—ฌ ์ด์ „ ํ”„๋ ˆ์ž„์˜ ์›์„ ์ง€์›๋‹ˆ๋‹ค.
  background(23, 23, 23);

  // draw() ํ•จ์ˆ˜๋Š” ๋งค ํ”„๋ ˆ์ž„(๊ธฐ๋ณธ 1์ดˆ์— 60๋ฒˆ)๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  // frameCount๋ผ๋Š” p5.js ๋‚ด์žฅ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ์›€์ง์ž„์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  for (let x = 0; x < width; x += 20) {
    // x ์ขŒํ‘œ์™€ ํ˜„์žฌ ํ”„๋ ˆ์ž„ ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ y ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    // sin() ํ•จ์ˆ˜๋Š” -1์—์„œ 1 ์‚ฌ์ด์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    // map() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ -1~1์˜ ๊ฐ’์„ ์บ”๋ฒ„์Šค ๋†’์ด(0~400) ๋ฒ”์œ„๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    let y = map(
      sin(x * 0.05 + frameCount * 0.05),
      -1,
      1,
      height * 0.2,
      height * 0.8
    );

    // y ์ขŒํ‘œ์— ๋”ฐ๋ผ ์›์˜ ํฌ๊ธฐ๋ฅผ ๋ณ€ํ™”์‹œํ‚ต๋‹ˆ๋‹ค.
    let circleSize = map(y, height * 0.2, height * 0.8, 20, 5);

    fill(100, 200, 255);
    circle(x, y, circleSize);
  }
}
  • frameCount: p5.js๊ฐ€ ์‹œ์ž‘๋œ ์ดํ›„์˜ ์ด ํ”„๋ ˆ์ž„ ์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. ์‹œ๊ฐ„์˜ ํ๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ฒ™๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • sin(x * 0.05 + frameCount * 0.05): x ์œ„์น˜์™€ frameCount๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ๊ฐ ์ ˆ์˜ ํŒŒ๋„ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. frameCount๊ฐ€ ๊ณ„์† ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ ํŒŒ๋„๊ฐ€ ๊ณ„์† ์›€์ง์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.
  • map(): sin() ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” -1~1์˜ ๊ฐ’์„ ์บ”๋ฒ„์Šค์˜ ์ƒ๋‹จ 20% ์ง€์ ์—์„œ ํ•˜๋‹จ 80% ์ง€์ ์œผ๋กœ, ๊ทธ๋ฆฌ๊ณ  ์›์˜ ํฌ๊ธฐ๋Š” 20์—์„œ 5๋กœ ๋งคํ•‘ํ•˜์—ฌ ๊นŠ์ด๊ฐ์„ ์ค๋‹ˆ๋‹ค.

ํšŒ์ „ํ•˜๋Š” ์‚ฌ๊ฐํ˜• (rotating square)

function setup() {
  createCanvas(800, 400);
}

function draw() {
  background(23, 23, 23); // ๋งˆ์ง€๋ง‰ ์ธ์ž์˜ ์•ŒํŒŒ๊ฐ’์— ์ˆซ์ž๋ฅผ ์“ฐ๋ฉด trail ํšจ๊ณผ

  push(); // ํ˜„์žฌ์˜ ์บ”๋ฒ„์Šค ์ƒํƒœ(์ขŒํ‘œ ๋“ฑ)๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  translate(width / 2, height / 2); // ์บ”๋ฒ„์Šค์˜ ์ค‘์‹ฌ์œผ๋กœ ์ขŒํ‘œ ์ด๋™

  // ํšŒ์ „ ๊ฐ๋„๋ฅผ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์กฐ๊ธˆ์”ฉ ๋ณ€๊ฒฝ
  rotate(frameCount * 0.01);

  // 12๊ฐœ์˜ ์‚ฌ๊ฐํ˜•์„ ์›ํ˜•์œผ๋กœ ๋ฐฐ์น˜
  for (let i = 0; i < 12; i++) {
    push(); // ํ˜„์žฌ ํšŒ์ „๋œ ์ƒํƒœ๋ฅผ ์ €์žฅ

    // ๊ฐ ์‚ฌ๊ฐํ˜•์„ ๋ฐฐ์น˜ํ•  ๊ฐ๋„๋ฅผ ๊ณ„์‚ฐ
    let angle = (TWO_PI / 12) * i;
    rotate(angle);

    // ์ค‘์‹ฌ์—์„œ 150px ๋–จ์–ด์ง„ ๊ณณ์— ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
    translate(150, 0);

    fill(255, 200, 0); // ๋…ธ๋ž€์ƒ‰
    noStroke();
    rectMode(CENTER); // ์‚ฌ๊ฐํ˜•์˜ ์ค‘์‹ฌ์„ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ฆฌ๋„๋ก ์„ค์ •
    rect(0, 0, 30, 30); // 30x30 ํฌ๊ธฐ์˜ ์‚ฌ๊ฐํ˜•

    pop(); // ํšŒ์ „๋œ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•˜์—ฌ ๋‹ค์Œ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
  }

  pop(); // ์บ”๋ฒ„์Šค์˜ ์›๋ž˜ ์ƒํƒœ(์ค‘์‹ฌ ์ด๋™ ์ „)๋ฅผ ๋ณต์›
}
  • push() / pop(): push()๋Š” ํ˜„์žฌ์˜ ์ขŒํ‘œ๊ณ„, ์ƒ‰์ƒ ๋“ฑ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ , pop()์€ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ €์žฅ๋œ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ขŒํ‘œ ๋ณ€ํ™”๊ฐ€ ์„œ๋กœ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„ ๋ณต์žกํ•œ ๊ทธ๋ž˜ํ”ฝ์„ ๊ทธ๋ฆฌ๊ธฐ ํŽธํ•ด์ง‘๋‹ˆ๋‹ค.
  • translate(): ์ขŒํ‘œ์˜ ์›์ (0,0)์„ ์ง€์ •ํ•œ ์œ„์น˜๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.
  • rotate(): ํ˜„์žฌ ์ขŒํ‘œ๊ณ„๋ฅผ ์ง€์ •ํ•œ ๊ฐ๋„๋งŒํผ ํšŒ์ „์‹œํ‚ต๋‹ˆ๋‹ค. frameCount๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๊ฐ„์— ๋”ฐ๋ผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํšŒ์ „ํ•ฉ๋‹ˆ๋‹ค.
  • TWO_PI: 360๋„๋ฅผ ๋ผ๋””์•ˆ ๊ฐ’์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค(์•ฝ 6.28). 12๊ฐœ์˜ ๋„ํ˜•์„ ์›ํ˜•์œผ๋กœ ๋ฐฐ์น˜ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ๋„ํ˜•๋งˆ๋‹ค TWO_PI / 12๋งŒํผ ํšŒ์ „์‹œํ‚ต๋‹ˆ๋‹ค.

2์ฐจ์› ํŒŒ๋™ ๊ทธ๋ฆฌ๋“œ (2D Wave Grid)

// No Animation
function setup() {
  createCanvas(800, 400);
  noLoop();
  background(25);
  noStroke();

  let cols = 20;
  let rows = 15;
  let spacingX = width / cols;
  let spacingY = height / rows;

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      let cx = i * spacingX + spacingX / 2;
      let cy = j * spacingY + spacingY / 2;
      let angle = i * 0.6 + j * 0.3;
      let r = 20 + 8 * sin(angle);
      fill(150, 80, 220, 250);
      ellipse(cx, cy, r, r);
    }
  }
}
// Animation using sin 
function setup() {
  createCanvas(800, 400);
  // noLoop()๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ draw() ํ•จ์ˆ˜๊ฐ€ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๊ณ„์† ํ˜ธ์ถœ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  // ์ด๊ฒƒ์ด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“œ๋Š” ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.
  background(25); // ๋ฐฐ๊ฒฝ์ƒ‰์„ ํ•œ ๋ฒˆ๋งŒ ์„ค์ •ํ•˜๋ฉด ์ด์ „ ํ”„๋ ˆ์ž„์˜ ๊ทธ๋ฆผ์ด ๋‚จ์•„์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  noStroke(); // ๋„ํ˜•์˜ ์™ธ๊ณฝ์„ ์„ ๊ทธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
}

function draw() {
  // ๋งค ํ”„๋ ˆ์ž„์ด ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ๋ฐฐ๊ฒฝ์„ ๋‹ค์‹œ ์น ํ•ด์ค๋‹ˆ๋‹ค.
  // ์ด๋ ‡๊ฒŒ ํ•ด์•ผ ์ด์ „ ํ”„๋ ˆ์ž„์—์„œ ๊ทธ๋ ธ๋˜ ์›๋“ค์ด ์ง€์›Œ์ง€๊ณ  ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์ด ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.
  background(25);

  // ๊ทธ๋ฆฌ๋“œ ์„ค์ •
  let cols = 20; // ๊ฐ€๋กœ ๋ฐฉํ–ฅ ์›์˜ ๊ฐœ์ˆ˜
  let rows = 15; // ์„ธ๋กœ ๋ฐฉํ–ฅ ์›์˜ ๊ฐœ์ˆ˜
  let spacingX = width / cols; // ๊ฐ€๋กœ ๋ฐฉํ–ฅ ์› ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ
  let spacingY = height / rows; // ์„ธ๋กœ ๋ฐฉํ–ฅ ์› ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ

  // ์ด์ค‘ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ 2์ฐจ์› ๊ทธ๋ฆฌ๋“œ ์ƒ์˜ ๋ชจ๋“  ์ ์— ๋Œ€ํ•ด ์›์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      // ๊ทธ๋ฆฌ๋“œ ์ƒ์˜ ๊ฐ ์ (i, j)์— ๋Œ€ํ•œ ์ค‘์‹ฌ ์ขŒํ‘œ(cx, cy)๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
      let cx = i * spacingX + spacingX / 2;
      let cy = j * spacingY + spacingY / 2;

      // --- ํ•ต์‹ฌ: ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์œ„ํ•œ ๊ฐ๋„ ๊ณ„์‚ฐ ---
      // ๊ฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๋ณ€ํ•˜๋Š” ๊ฐ’์ธ frameCount๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ๋„๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
      // i์™€ j์— ๊ฐ๊ฐ ๋‹ค๋ฅธ ๊ฐ€์ค‘์น˜(0.6, 0.3)๋ฅผ ๊ณฑํ•ด ๋Œ€๊ฐ์„  ๋ฐฉํ–ฅ์œผ๋กœ ํŒŒ๋„๊ฐ€ ์น˜๋Š” ํšจ๊ณผ๋ฅผ ๋ƒ…๋‹ˆ๋‹ค.
      let angle = i * 0.6 + j * 0.3 + frameCount * 0.05;

      // sin() ํ•จ์ˆ˜๋Š” -1์—์„œ 1 ์‚ฌ์ด์˜ ๊ฐ’์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
      // ์ด ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์›์˜ ๋ฐ˜์ง€๋ฆ„(r)์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ณ€ํ™”์‹œํ‚ต๋‹ˆ๋‹ค.
      // 8 * sin(angle)์˜ ๊ฒฐ๊ณผ๋Š” -8์—์„œ 8 ์‚ฌ์ด๊ฐ€ ๋˜๊ณ ,
      // ์—ฌ๊ธฐ์— ๊ธฐ๋ณธ ๋ฐ˜์ง€๋ฆ„ 20์„ ๋”ํ•˜๋ฉด ์ตœ์ข… ๋ฐ˜์ง€๋ฆ„์€ 12์—์„œ 28 ์‚ฌ์ด๋กœ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค.
      let r = 20 + 8 * sin(angle);

      // ์›์˜ ์ƒ‰์ƒ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. (๋ณด๋ผ์ƒ‰)
      fill(150, 80, 220, 250);

      // ๊ณ„์‚ฐ๋œ ์ค‘์‹ฌ ์ขŒํ‘œ(cx, cy)์™€ ๋ณ€ํ•˜๋Š” ๋ฐ˜์ง€๋ฆ„(r)์„ ์ด์šฉํ•˜์—ฌ ์›์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
      ellipse(cx, cy, r, r);
    }
  }
}
  • ๊ทœ์น™์ ์ธ ๊ฒฉ์ž ์•ˆ์—์„œ๋„ sin()๋กœ ์ˆ˜ํ•™์  ๋ณ€ํ˜•์„ ์ฃผ์–ด ์œ ๊ธฐ์ ์ธ ํŒจํ„ด์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0๊ฐœ์˜ ๋Œ“๊ธ€