RustでGenerative Artに挑戦

2 min読了の目安(約1700字TECH技術記事

幾何的な模様をグリグリするアニメーションを作りたくて、Generative Artを勉強しようと思っていました。
そんなとき、Rustのクリエイティブコーディングライブラリnannouがあることを知ったので、さわってみました。

Generative Artは初めてですが、すごくシンプルな構造でこんな複雑な絵ができるんですねぇ。
Rustもさわれて、Generative Artも勉強できるとは最高ですね!
コツコツやっていこうと思います。

以下にコードをのせときます!

use nannou::prelude::*;

struct Model {}

fn draw_circle(draw:&Draw, p:Vector2, r:f32) {
    let points = (0..=360).map(|i| {
        let radian = deg_to_rad(i as f32);
        let x = radian.sin() * r;
        let y = radian.cos() * r;
        (pt2(x, y), BLACK)
    });

    draw.polyline()
        .xy(p)
        .weight(1.)
        .points_colored(points);
}

fn render(draw:&Draw, p:Vector2, r:f32, level:u32) {
    if level <= 0 {return ;}

    draw_circle(draw, p, r);

    let r = r / 2.;

    for i in (0..=360).step_by(45) {
        let radian = deg_to_rad(i as f32);
        let p = p + vec2(radian.sin() * r, radian.cos() * r);

        render(draw, p, r, level - 1);
    }

}

fn main() {
    nannou::app(model)
        .event(event)
        .simple_window(view)
        .run();
}

fn model(_app: &App) -> Model {
    Model {}
}

fn event(_app: &App, _model: &mut Model, _event: Event) {
}

fn view(app: &App, _model: &Model, frame: Frame) {
    let draw = app.draw();

    draw.background().color(WHITE);

    render(&draw, vec2(0., 0.), 300., 4);

    draw.to_frame(app, &frame).unwrap();

    app.main_window().capture_frame(captured_frame_path(app));
}

fn captured_frame_path(app: &App) -> std::path::PathBuf {
    app.project_path()
        .expect("failed to locate `project_path`")
        .join("capture")
        .with_extension("png")
}