🔮 :: Particle Flock

BamgasiJM·2025년 9월 20일

Nannou <Generative Art>

목록 보기
22/55
post-thumbnail

📝 Rust Code

use nannou::prelude::*;

struct Particle {
    position: Vec2,
    velocity: Vec2,
}

struct Model {
    particles: Vec<Particle>,
}

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

fn model(app: &App) -> Model {
    app.new_window().size(1000, 1000).view(view).build().unwrap();
    let mut particles = Vec::new();
    let window_rect = app.window_rect();
    for _ in 0..5000 {  // 입자 개수
        particles.push(Particle {
            position: vec2(
                random_f32() * window_rect.w() - window_rect.w() / 2.0,
                random_f32() * window_rect.h() - window_rect.h() / 2.0
            ),
            velocity: vec2(random_f32() - 0.5, random_f32() - 0.5) * 2.0,
        });
    }
    Model { particles }
}

fn update(app: &App, model: &mut Model, _update: Update) {
    let mouse_pos = app.mouse.position();
    
    for p in &mut model.particles {
        // 마우스와의 거리 계산 및 힘 적용
        let distance_to_mouse = (mouse_pos - p.position).length();
        if distance_to_mouse > 0.0 {
            let force = (mouse_pos - p.position).normalize() * 0.1;
            p.velocity += force;
        }
        
        p.position += p.velocity;
        
        // 경계 체크: 화면 밖으로 나가면 반사
        let bound = app.window_rect();
        let mut bounce = false;
        
        if p.position.x > bound.right() {
            p.position.x = bound.right();
            p.velocity.x *= -1.0;
            bounce = true;
        } else if p.position.x < bound.left() {
            p.position.x = bound.left();
            p.velocity.x *= -1.0;
            bounce = true;
        }
        
        if p.position.y > bound.top() {
            p.position.y = bound.top();
            p.velocity.y *= -1.0;
            bounce = true;
        } else if p.position.y < bound.bottom() {
            p.position.y = bound.bottom();
            p.velocity.y *= -1.0;
            bounce = true;
        }
        
        // 경계에서 튕길 때 속도 감쇠
        if bounce {
            p.velocity *= 0.8;
        }
    }
}

fn view(app: &App, model: &Model, frame: Frame) {
    let draw = app.draw();
    draw.background().color(BLACK);

    for p in &model.particles {
        // 속도에 따라 색상 변화 (length() 사용)
        let speed = p.velocity.length();
        let hue = (speed / 10.0).min(1.0);
        
        draw.ellipse()
            .xy(p.position)
            .radius(1.5)
            .color(hsla(hue, 1.0, 0.5, 1.0));  // 속도에 따라 색상 변화
    }

    // 마우스 위치 표시 (선택사항)
    let mouse_pos = app.mouse.position();
    draw.ellipse()
        .xy(mouse_pos)
        .radius(8.0)
        .color(WHITE)
        .stroke(WHITE)
        .stroke_weight(2.0);

    draw.to_frame(app, &frame).unwrap();
}
profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0개의 댓글