๐Ÿ”ฎ :: Dynamic Color Grid ver.1

BamgasiJMยท2025๋…„ 9์›” 20์ผ

Nannou <Generative Art>

๋ชฉ๋ก ๋ณด๊ธฐ
23/55
post-thumbnail

๐Ÿ“ Rust Code

use nannou::prelude::*;
use rand::Rng;

struct Model {
    color_coefficients: Vec<f32>, // ๊ฐ ๊ทธ๋ฆฌ๋“œ ์…€์˜ hue ๊ณ„์ˆ˜ ๊ฐ’์„ ์ €์žฅ
    grid_size: usize,             // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ (N x N)
    max_grid_size: usize,         // ์ตœ๋Œ€ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ (2^8 = 256)
    show_too_dense: bool,         // Too Dense ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ ์—ฌ๋ถ€
}

fn main() {
    nannou::app(model).update(update).run();
}

fn model(app: &App) -> Model {
    app.new_window()
        .size(1000, 1000)
        .view(view)
        .key_pressed(key_pressed)
        .build()
        .unwrap();
    
    // ์ดˆ๊ธฐ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋กœ ์„ค์ •, ์ตœ๋Œ€ ํฌ๊ธฐ๋Š” 2^8 = 256
    let grid_size = 2;
    let max_grid_size = 256; // 2^8
    let total_cells = grid_size * grid_size;
    
    // ๋žœ๋คํ•œ hue ๊ณ„์ˆ˜ ๊ฐ’์œผ๋กœ ๊ทธ๋ฆฌ๋“œ ์ƒ‰์ƒ ์ดˆ๊ธฐํ™”
    let mut rng = rand::thread_rng();
    let color_coefficients = (0..total_cells).map(|_| rng.gen_range(0.0..1.0)).collect();
    
    Model {
        color_coefficients,
        grid_size,
        max_grid_size,
        show_too_dense: false,
    }
}

fn update(_app: &App, _model: &mut Model, _update: Update) {
    // Too Dense ๋ฉ”์‹œ์ง€๋ฅผ ์ผ์ • ์‹œ๊ฐ„ ํ›„์— ์‚ฌ๋ผ์ง€๊ฒŒ ํ•จ
    // ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„: ๋‹ค์Œ ํ”„๋ ˆ์ž„์—์„œ ๊ณ„์† ํ‘œ์‹œ
}

fn view(app: &App, model: &Model, frame: Frame) {
    let draw = app.draw();
    let win = app.window_rect();
    
    // ๋ฐฐ๊ฒฝ์„ ๊ฒ€์€์ƒ‰์œผ๋กœ
    draw.background().color(BLACK);
    
    let grid_size = model.grid_size;
    let cell_width = win.w() / grid_size as f32;
    let cell_height = win.h() / grid_size as f32;
    
    for i in 0..grid_size {
        for j in 0..grid_size {
            let idx = i * grid_size + j;
            
            // ์ธ๋ฑ์Šค ๋ฒ”์œ„ ํ™•์ธ
            if idx >= model.color_coefficients.len() {
                continue;
            }
            
            let color_coefficient = model.color_coefficients[idx];
            
            let x = win.left() + cell_width * (j as f32 + 0.5);
            let y = win.top() - cell_height * (i as f32 + 0.5);
            
            draw.rect()
                .x_y(x, y)
                .w_h(cell_width, cell_height)
                .color(hsl(0.8, color_coefficient, 0.4));
        }
    }
    
    // Too Dense ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
    if model.show_too_dense {
        draw.text("Too Dense")
            .x_y(0.0, 0.0)
            .color(WHITE)
            .font_size(48)
            .align_text_middle_y();
    }
    
    draw.to_frame(app, &frame).unwrap();
}

fn key_pressed(_app: &App, model: &mut Model, key: Key) {
    match key {
        Key::C => {
            // C ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ชจ๋“  ์…€์˜ hue ๊ณ„์ˆ˜ ๊ฐ’์„ ๋žœ๋คํ•˜๊ฒŒ ๋ณ€๊ฒฝ
            let total_cells = model.grid_size * model.grid_size;
            
            // ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด ํฌ๊ธฐ๊ฐ€ ๋งž๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ํ•„์š”์‹œ resize
            if model.color_coefficients.len() != total_cells {
                model.color_coefficients.resize(total_cells, 0.0);
            }
            
            let mut rng = rand::thread_rng();
            for coefficient in &mut model.color_coefficients {
                *coefficient = rng.gen_range(0.0..1.0);
            }
            model.show_too_dense = false;
        }
        Key::Up => {
            // ์œ„ ํ™”์‚ดํ‘œ: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ 2๋ฐฐ (์ตœ๋Œ€ ํฌ๊ธฐ ์ œํ•œ)
            if model.grid_size * 2 <= model.max_grid_size {
                model.grid_size *= 2;
                let total_cells = model.grid_size * model.grid_size;
                
                // ์ƒˆ๋กœ์šด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด ์žฌ์ƒ์„ฑ
                let mut rng = rand::thread_rng();
                model.color_coefficients = (0..total_cells)
                    .map(|_| rng.gen_range(0.0..1.0))
                    .collect();
                model.show_too_dense = false;
            } else {
                // ์ตœ๋Œ€ ํฌ๊ธฐ ์ดˆ๊ณผ์‹œ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
                model.show_too_dense = true;
            }
        }
        Key::Down => {
            // ์•„๋ž˜ ํ™”์‚ดํ‘œ: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ ์ ˆ๋ฐ˜ (์ตœ์†Œ 1 ์œ ์ง€)
            if model.grid_size > 1 {
                model.grid_size /= 2;
                let total_cells = model.grid_size * model.grid_size;
                
                // ์ƒˆ๋กœ์šด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด ์žฌ์ƒ์„ฑ
                let mut rng = rand::thread_rng();
                model.color_coefficients = (0..total_cells)
                    .map(|_| rng.gen_range(0.0..1.0))
                    .collect();
            }
            model.show_too_dense = false;
        }
        _ => {}
    }
}

๐Ÿ“ Rust Code + Comment

// nannou prelude๋Š” ์•ฑ, ๊ทธ๋ฆฌ๊ธฐ, ์ฐฝ ๊ด€๋ฆฌ ๋“ฑ nannou์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๋Œ€๋ถ€๋ถ„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
use nannou::prelude::*;
// ๋‚œ์ˆ˜ ์ƒ์„ฑ์„ ์œ„ํ•ด rand ํฌ๋ ˆ์ดํŠธ์˜ Rng ํŠธ๋ ˆ์ดํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
use rand::Rng;

// ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ „์ฒด ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ตฌ์กฐ์ฒด์ž…๋‹ˆ๋‹ค.
struct Model {
    // ๊ฐ ๊ทธ๋ฆฌ๋“œ ์…€์˜ ์ƒ‰์ƒ(์ฑ„๋„) ๊ณ„์ˆ˜ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ฒกํ„ฐ(๋™์  ๋ฐฐ์—ด)์ž…๋‹ˆ๋‹ค.
    color_coefficients: Vec<f32>,
    // ๊ทธ๋ฆฌ๋“œ์˜ ํ•œ ๋ณ€์˜ ์…€ ๊ฐœ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. (์˜ˆ: 8์ด๋ฉด 8x8 ๊ทธ๋ฆฌ๋“œ)
    grid_size: usize,
    // ๊ทธ๋ฆฌ๋“œ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. (2^8 = 256)
    max_grid_size: usize,
    // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ ์ตœ๋Œ€์น˜๋ฅผ ์ดˆ๊ณผํ–ˆ์„ ๋•Œ "Too Dense" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
    show_too_dense: bool,
}

// ํ”„๋กœ๊ทธ๋žจ์˜ ์‹œ์ž‘์ (entry point)์ž…๋‹ˆ๋‹ค.
fn main() {
    // nannou ์•ฑ์„ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    // model ํ•จ์ˆ˜๋กœ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ๋งŒ๋“ค๊ณ , update ํ•จ์ˆ˜๋กœ ์ƒํƒœ๋ฅผ ๊ฐฑ์‹ ํ•˜๋ฉฐ, view ํ•จ์ˆ˜๋กœ ํ™”๋ฉด์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
    nannou::app(model).update(update).run();
}

// ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜์–ด ์ดˆ๊ธฐ ๋ชจ๋ธ(์ƒํƒœ)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
fn model(app: &App) -> Model {
    // ์ƒˆ ์ฐฝ์„ ์ƒ์„ฑํ•˜๊ณ  ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    app.new_window()
        .size(1000, 1000) // ์ฐฝ ํฌ๊ธฐ๋ฅผ ๊ฐ€๋กœ 1000, ์„ธ๋กœ 1000 ํ”ฝ์…€๋กœ ์„ค์ •
        .view(view) // ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ™”๋ฉด์„ ๊ทธ๋ฆด ํ•จ์ˆ˜๋กœ view ํ•จ์ˆ˜๋ฅผ ์ง€์ •
        .key_pressed(key_pressed) // ํ‚ค๋ณด๋“œ ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์„ ๋•Œ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜๋กœ key_pressed ํ•จ์ˆ˜๋ฅผ ์ง€์ •
        .build() // ์„ค์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ์ฐฝ์„ ๋นŒ๋“œ
        .unwrap(); // ์ฐฝ ์ƒ์„ฑ์— ์‹คํŒจํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์„ ์ค‘๋‹จ

    // ์ดˆ๊ธฐ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2x2๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    let grid_size = 2;
    // ์ตœ๋Œ€ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 256x256์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. (2์˜ 8์Šน)
    let max_grid_size = 256;
    // ์ „์ฒด ์…€์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. (grid_size * grid_size)
    let total_cells = grid_size * grid_size;

    // ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
    let mut rng = rand::thread_rng();
    // 0๋ถ€ํ„ฐ total_cells - 1๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ๊ฐ ์…€์— ๋Œ€ํ•œ ๋žœ๋คํ•œ ์ƒ‰์ƒ ๊ณ„์ˆ˜(0.0 ~ 1.0)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    let color_coefficients = (0..total_cells).map(|_| rng.gen_range(0.0..1.0)).collect();

    // ์ƒ์„ฑ๋œ ๊ฐ’๋“ค๋กœ Model ๊ตฌ์กฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    Model {
        color_coefficients,
        grid_size,
        max_grid_size,
        show_too_dense: false, // ์ฒ˜์Œ์—๋Š” "Too Dense" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š์Œ
    }
}

// ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ˜ธ์ถœ๋˜์–ด ๋ชจ๋ธ์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. (ํ˜„์žฌ๋Š” ์•„๋ฌด ์ž‘์—…๋„ ํ•˜์ง€ ์•Š์Œ)
fn update(_app: &App, _model: &mut Model, _update: Update) {
    // ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๊ธฐ์— 'show_too_dense'๋ฅผ ํŠน์ • ์‹œ๊ฐ„ ํ›„์— false๋กœ ๋ฐ”๊พธ๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
}

// ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ™”๋ฉด์— ๋‚ด์šฉ์„ ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
fn view(app: &App, model: &Model, frame: Frame) {
    // ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์œ„ํ•œ Draw ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    let draw = app.draw();
    // ํ˜„์žฌ ์ฐฝ์˜ ๊ฒฝ๊ณ„(ํฌ๊ธฐ ๋ฐ ์œ„์น˜) ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    let win = app.window_rect();

    // ๋ฐฐ๊ฒฝ์„ ๊ฒ€์€์ƒ‰์œผ๋กœ ์น ํ•ฉ๋‹ˆ๋‹ค.
    draw.background().color(BLACK);

    // ํ˜„์žฌ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    let grid_size = model.grid_size;
    // ์ฐฝ์˜ ๋„ˆ๋น„๋ฅผ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ์…€์˜ ๋„ˆ๋น„๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    let cell_width = win.w() / grid_size as f32;
    // ์ฐฝ์˜ ๋†’์ด๋ฅผ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ์…€์˜ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    let cell_height = win.h() / grid_size as f32;

    // ๋ชจ๋“  ๊ทธ๋ฆฌ๋“œ ์…€์„ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ ์ด์ค‘ ๋ฐ˜๋ณต๋ฌธ์ž…๋‹ˆ๋‹ค.
    for i in 0..grid_size { // ํ–‰(row) ๋ฐ˜๋ณต
        for j in 0..grid_size { // ์—ด(column) ๋ฐ˜๋ณต
            // 2์ฐจ์› ์ธ๋ฑ์Šค (i, j)๋ฅผ 1์ฐจ์› ๋ฒกํ„ฐ์˜ ์ธ๋ฑ์Šค๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
            let idx = i * grid_size + j;

            // ๊ณ„์‚ฐ๋œ ์ธ๋ฑ์Šค๊ฐ€ color_coefficients ๋ฒกํ„ฐ์˜ ์œ ํšจํ•œ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
            // (๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ฅ˜ ๋ฐฉ์ง€)
            if idx >= model.color_coefficients.len() {
                continue; // ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋ฉด ๋‹ค์Œ ์…€๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.
            }

            // ํ˜„์žฌ ์…€์˜ ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
            let color_coefficient = model.color_coefficients[idx];

            // ์…€์„ ๊ทธ๋ฆด ํ™”๋ฉด์ƒ์˜ x, y ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
            // Nannou์˜ ์ขŒํ‘œ๊ณ„๋Š” ์ค‘์•™์ด (0.0, 0.0)์ž…๋‹ˆ๋‹ค.
            let x = win.left() + cell_width * (j as f32 + 0.5);
            let y = win.top() - cell_height * (i as f32 + 0.5);

            // ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
            draw.rect()
                .x_y(x, y) // ์‚ฌ๊ฐํ˜•์˜ ์ค‘์‹ฌ ์ขŒํ‘œ ์„ค์ •
                .w_h(cell_width, cell_height) // ์‚ฌ๊ฐํ˜•์˜ ๋„ˆ๋น„์™€ ๋†’์ด ์„ค์ •
                .color(hsl(0.8, color_coefficient, 0.4)); // HSL ์ƒ‰์ƒ ๋ชจ๋ธ๋กœ ์ƒ‰ ์ง€์ •
                                                                // H(์ƒ‰์ƒ): 0.8 (ํ‘ธ๋ฅธ ๊ณ„์—ด)
                                                                // S(์ฑ„๋„): ๋žœ๋ค ๊ณ„์ˆ˜ ๊ฐ’
                                                                // L(๋ช…๋„): 0.4
        }
    }

    // 'show_too_dense' ํ”Œ๋ž˜๊ทธ๊ฐ€ true์ด๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
    if model.show_too_dense {
        draw.text("Too Dense") // ํ‘œ์‹œํ•  ํ…์ŠคํŠธ
            .x_y(0.0, 0.0) // ํ™”๋ฉด ์ค‘์•™์— ์œ„์น˜
            .color(WHITE) // ํ…์ŠคํŠธ ์ƒ‰์ƒ์„ ํฐ์ƒ‰์œผ๋กœ
            .font_size(48) // ํฐํŠธ ํฌ๊ธฐ๋ฅผ 48๋กœ
            .align_text_middle_y(); // ์ˆ˜์ง ์ •๋ ฌ์„ ์ค‘์•™์œผ๋กœ
    }

    // ์ง€๊ธˆ๊นŒ์ง€ ๊ทธ๋ฆฐ ๋ชจ๋“  ๋‚ด์šฉ์„ ํ”„๋ ˆ์ž„์— ๋ Œ๋”๋งํ•˜์—ฌ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
    draw.to_frame(app, &frame).unwrap();
}

// ํ‚ค๋ณด๋“œ ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
fn key_pressed(_app: &App, model: &mut Model, key: Key) {
    // ๋ˆŒ๋ฆฐ ํ‚ค์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    match key {
        // 'C' ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๊ฒฝ์šฐ
        Key::C => {
            // ํ˜„์žฌ ๊ทธ๋ฆฌ๋“œ์˜ ์ด ์…€ ๊ฐœ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
            let total_cells = model.grid_size * model.grid_size;

            // ํ˜น์‹œ ๋ชจ๋ฅผ ์ƒํ™ฉ์— ๋Œ€๋น„ํ•ด ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ํ˜„์žฌ ์…€ ๊ฐœ์ˆ˜์™€ ๋งž์ถฅ๋‹ˆ๋‹ค.
            if model.color_coefficients.len() != total_cells {
                model.color_coefficients.resize(total_cells, 0.0);
            }

            // ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
            let mut rng = rand::thread_rng();
            // ๋ชจ๋“  ์ƒ‰์ƒ ๊ณ„์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ๋žœ๋ค ๊ฐ’์œผ๋กœ ๋ฎ์–ด์”๋‹ˆ๋‹ค.
            for coefficient in &mut model.color_coefficients {
                *coefficient = rng.gen_range(0.0..1.0);
            }
            // "Too Dense" ๋ฉ”์‹œ์ง€๋Š” ์ˆจ๊น๋‹ˆ๋‹ค.
            model.show_too_dense = false;
        }
        // ์œ„์ชฝ ํ™”์‚ดํ‘œ ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๊ฒฝ์šฐ
        Key::Up => {
            // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋กœ ๋Š˜๋ ธ์„ ๋•Œ ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ๋„˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
            if model.grid_size * 2 <= model.max_grid_size {
                // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋กœ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค.
                model.grid_size *= 2;
                let total_cells = model.grid_size * model.grid_size;

                // ์ƒˆ๋กœ์šด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด์„ ์™„์ „ํžˆ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
                let mut rng = rand::thread_rng();
                model.color_coefficients = (0..total_cells)
                    .map(|_| rng.gen_range(0.0..1.0))
                    .collect();
                // "Too Dense" ๋ฉ”์‹œ์ง€๋Š” ์ˆจ๊น๋‹ˆ๋‹ค.
                model.show_too_dense = false;
            } else {
                // ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด "Too Dense" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ํ”Œ๋ž˜๊ทธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
                model.show_too_dense = true;
            }
        }
        // ์•„๋ž˜์ชฝ ํ™”์‚ดํ‘œ ํ‚ค๋ฅผ ๋ˆŒ๋ €์„ ๊ฒฝ์šฐ
        Key::Down => {
            // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ 1๋ณด๋‹ค ํด ๋•Œ๋งŒ (์ตœ์†Œ 1x1์€ ์œ ์ง€) ํฌ๊ธฐ๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค.
            if model.grid_size > 1 {
                // ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ ์ ˆ๋ฐ˜์œผ๋กœ ์ค„์ž…๋‹ˆ๋‹ค.
                model.grid_size /= 2;
                let total_cells = model.grid_size * model.grid_size;

                // ์ƒˆ๋กœ์šด ํฌ๊ธฐ์— ๋งž๊ฒŒ ์ƒ‰์ƒ ๊ณ„์ˆ˜ ๋ฐฐ์—ด์„ ์™„์ „ํžˆ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
                let mut rng = rand::thread_rng();
                model.color_coefficients = (0..total_cells)
                    .map(|_| rng.gen_range(0.0..1.0))
                    .collect();
            }
            // "Too Dense" ๋ฉ”์‹œ์ง€๋Š” ์ˆจ๊น๋‹ˆ๋‹ค.
            model.show_too_dense = false;
        }
        // ์œ„์—์„œ ์ง€์ •ํ•œ ํ‚ค ์™ธ์˜ ๋‹ค๋ฅธ ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์„ ๊ฒฝ์šฐ
        _ => {} // ์•„๋ฌด ์ž‘์—…๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    }
}

๐Ÿ“ ์ฝ”๋“œ ๋ถ„์„ (Gemini)

1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ (use):

  • nannou::prelude::*: Nannou ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ฑฐ์˜ ๋ชจ๋“  ์ฃผ์š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์•ฑ ์ƒ์„ฑ, ๊ทธ๋ฆฌ๊ธฐ, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋“ฑ์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ์š”์†Œ๋“ค์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • rand::Rng: ๋‚œ์ˆ˜ ์ƒ์„ฑ์„ ์œ„ํ•œ Rng ํŠธ๋ ˆ์ดํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. gen_range์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ๋ฒ”์œ„์˜ ๋‚œ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. Model ๊ตฌ์กฐ์ฒด:

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

  • color_coefficients: ๊ฐ ๊ทธ๋ฆฌ๋“œ ์…€์˜ ์ƒ‰์ƒ(์—ฌ๊ธฐ์„œ๋Š” ์ƒ‰์ƒ(hue)์˜ ๊ณ„์ˆ˜)์„ ๊ฒฐ์ •ํ•˜๋Š” f32 ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๋Š” ๋ฒกํ„ฐ์ž…๋‹ˆ๋‹ค.

  • grid_size: ํ˜„์žฌ ๊ทธ๋ฆฌ๋“œ์˜ ํฌ๊ธฐ (์˜ˆ: grid_size๊ฐ€ 8์ด๋ฉด 8x8 ๊ทธ๋ฆฌ๋“œ)๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  • max_grid_size: ๊ทธ๋ฆฌ๋“œ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  • show_too_dense: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ ์ตœ๋Œ€์น˜๋ฅผ ์ดˆ๊ณผํ–ˆ์„ ๋•Œ "Too Dense" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์ž…๋‹ˆ๋‹ค.

3. main ํ•จ์ˆ˜:

  • ํ”„๋กœ๊ทธ๋žจ์˜ ์ง„์ž…์ ์ž…๋‹ˆ๋‹ค.

  • nannou::app(model).update(update).run(): Nannou ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    • app: model ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์•ฑ์˜ ์ดˆ๊ธฐ ์ƒํƒœ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • update: update ํ•จ์ˆ˜๋ฅผ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ˜ธ์ถœํ•˜์—ฌ ์•ฑ์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

    • run: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

4. model ํ•จ์ˆ˜:

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฒ˜์Œ ์‹œ์ž‘๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. Model ๊ตฌ์กฐ์ฒด์˜ ์ดˆ๊ธฐ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • app.new_window(): ์ƒˆ ์ฐฝ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • .size(1000, 1000): ์ฐฝ์˜ ๊ฐ€๋กœ์™€ ์„ธ๋กœ ํฌ๊ธฐ๋ฅผ 1000ํ”ฝ์…€๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • .view(view): view ํ•จ์ˆ˜๋ฅผ ๋ Œ๋”๋ง(๊ทธ๋ฆฌ๊ธฐ) ํ•จ์ˆ˜๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

    • .key_pressed(key_pressed): key_pressed ํ•จ์ˆ˜๋ฅผ ํ‚ค๋ณด๋“œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

    • .build().unwrap(): ์„ค์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ์ฐฝ์„ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. unwrap()์€ ๋นŒ๋“œ ์‹คํŒจ ์‹œ ํ”„๋กœ๊ทธ๋žจ์„ ํŒจ๋‹‰ ์ƒํƒœ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  • ์ดˆ๊ธฐ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋กœ ์„ค์ •ํ•˜๊ณ , ์ตœ๋Œ€ ํฌ๊ธฐ๋Š” 256 (2์˜ 8์ œ๊ณฑ)์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • rand::thread_rng(): ํ˜„์žฌ ์Šค๋ ˆ๋“œ์—์„œ ์‚ฌ์šฉํ•  ๋‚œ์ˆ˜ ์ƒ์„ฑ๊ธฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

  • color_coefficients: map๊ณผ collect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐ ๊ทธ๋ฆฌ๋“œ ์…€ ๊ฐœ์ˆ˜๋งŒํผ 0.0์—์„œ 1.0 ์‚ฌ์ด์˜ ๋ฌด์ž‘์œ„ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฒกํ„ฐ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

  • ์„ค์ •๋œ ๊ฐ’๋“ค๋กœ Model ๊ตฌ์กฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

5. update ํ•จ์ˆ˜:

  • ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค view ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ง์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์•ฑ์˜ ๋…ผ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • ํ˜„์žฌ ์ฝ”๋“œ์—์„œ๋Š” ๋น„์–ด ์žˆ์ง€๋งŒ, ์˜ˆ๋ฅผ ๋“ค์–ด "Too Dense" ๋ฉ”์‹œ์ง€๋ฅผ ํŠน์ • ์‹œ๊ฐ„ ํ›„์— ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•˜๋Š” ๋กœ์ง์„ ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

6. view ํ•จ์ˆ˜:

๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ™”๋ฉด์— ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • app.draw(): ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์œ„ํ•œ Draw ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • draw.background().color(BLACK): ์ฐฝ ๋ฐฐ๊ฒฝ์„ ๊ฒ€์€์ƒ‰์œผ๋กœ ์น ํ•ฉ๋‹ˆ๋‹ค.

  • cell_width, cell_height: ์ „์ฒด ์ฐฝ ํฌ๊ธฐ๋ฅผ ํ˜„์žฌ ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ์…€์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • ์ด์ค‘ for ๋ฃจํ”„: ๊ทธ๋ฆฌ๋“œ์˜ ๋ชจ๋“  ํ–‰(i)๊ณผ ์—ด(j)์„ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ ์…€์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

    • idx: 1์ฐจ์› ๋ฒกํ„ฐ์ธ color_coefficients์—์„œ ํ˜„์žฌ ์…€(i, j)์— ํ•ด๋‹นํ•˜๋Š” ์ƒ‰์ƒ ๊ณ„์ˆ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ ์ธ๋ฑ์Šค๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

    • idx >= model.color_coefficients.len(): ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ณผ์ •์—์„œ ์ธ๋ฑ์Šค๊ฐ€ ๋ฒกํ„ฐ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์•ˆ์ „์žฅ์น˜์ž…๋‹ˆ๋‹ค.

  • x, y: ์…€์ด ๊ทธ๋ ค์งˆ ํ™”๋ฉด์ƒ์˜ ์ค‘์‹ฌ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. Nannou์˜ ์ขŒํ‘œ๊ณ„๋Š” ์ค‘์•™์ด (0,0)์ž…๋‹ˆ๋‹ค.

  • draw.rect(): ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

    • .x_y(x, y): ์‚ฌ๊ฐํ˜•์˜ ์ค‘์‹ฌ ์ขŒํ‘œ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • .w_h(cell_width, cell_height): ์‚ฌ๊ฐํ˜•์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • .color(hsl(0.8, color_coefficient, 0.4)): ์…€์˜ ์ƒ‰์ƒ์„ HSL ์ƒ‰ ๊ณต๊ฐ„์„ ์ด์šฉํ•ด ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

      • Hue (์ƒ‰์ƒ): 0.8 (ํ‘ธ๋ฅธ ๊ณ„์—ด)๋กœ ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
      • Saturation (์ฑ„๋„): color_coefficient ๊ฐ’ (0.0 ~ 1.0)์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
      • Lightness (๋ช…๋„): 0.4๋กœ ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • if model.show_too_dense: show_too_dense๊ฐ€ true์ด๋ฉด ํ™”๋ฉด ์ค‘์•™์— "Too Dense"๋ผ๋Š” ํ…์ŠคํŠธ๋ฅผ ํฐ์ƒ‰์œผ๋กœ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.

  • draw.to_frame(app, &frame).unwrap(): ์ง€๊ธˆ๊นŒ์ง€ ๊ทธ๋ฆฐ ๋ชจ๋“  ๋‚ด์šฉ์„ ํ”„๋ ˆ์ž„์— ์ตœ์ข…์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜์—ฌ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

7. key_pressed ํ•จ์ˆ˜:

  • ํ‚ค๋ณด๋“œ ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. Model์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์ƒํ˜ธ์ž‘์šฉ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • match key: ๋ˆŒ๋ฆฐ ํ‚ค์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • Key::C: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋Š” ์œ ์ง€ํ•œ ์ฑ„, ๋ชจ๋“  ์…€์˜ ์ƒ‰์ƒ ๊ณ„์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ๋‚œ์ˆ˜๋กœ ๋‹ค์‹œ ์ฑ„์›๋‹ˆ๋‹ค. show_too_dense ํ”Œ๋ž˜๊ทธ๋Š” false๋กœ ๋ฆฌ์…‹ํ•ฉ๋‹ˆ๋‹ค.

  • Key::Up: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋กœ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค.

    • ๋‹จ, ์ƒˆ๋กœ์šด ํฌ๊ธฐ๊ฐ€ max_grid_size๋ฅผ ์ดˆ๊ณผํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

    • ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ์ƒˆ๋กœ์šด ์ด ์…€ ๊ฐœ์ˆ˜์— ๋งž์ถฐ color_coefficients ๋ฒกํ„ฐ๋ฅผ ์™„์ „ํžˆ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด show_too_dense๋ฅผ true๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  • Key::Down: ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๋ฅผ 2๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค.

    • ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ 1๋ณด๋‹ค ํด ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

    • ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ color_coefficients ๋ฒกํ„ฐ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • show_too_dense ํ”Œ๋ž˜๊ทธ๋Š” false๋กœ ๋ฆฌ์…‹ํ•ฉ๋‹ˆ๋‹ค.

  • _ => {}: ๊ทธ ์™ธ ๋‹ค๋ฅธ ํ‚ค๊ฐ€ ๋ˆŒ๋ ธ์„ ๋•Œ๋Š” ์•„๋ฌด ์ž‘์—…๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


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

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