

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;
}
_ => {}
}
}
// 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;
}
// ์์์ ์ง์ ํ ํค ์ธ์ ๋ค๋ฅธ ํค๊ฐ ๋๋ ธ์ ๊ฒฝ์ฐ
_ => {} // ์๋ฌด ์์
๋ ํ์ง ์์ต๋๋ค.
}
}
nannou::prelude::*: Nannou ํ๋ ์์ํฌ์ ๊ฑฐ์ ๋ชจ๋ ์ฃผ์ ๊ธฐ๋ฅ์ ๊ฐ์ ธ์ต๋๋ค. ์ฑ ์์ฑ, ๊ทธ๋ฆฌ๊ธฐ, ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฑ์ ํ์ํ ๊ธฐ๋ณธ ์์๋ค์ด ํฌํจ๋์ด ์์ต๋๋ค.
rand::Rng: ๋์ ์์ฑ์ ์ํ Rng ํธ๋ ์ดํธ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. gen_range์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ๋ฒ์์ ๋์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์ ์ฅํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋๋ค.
color_coefficients: ๊ฐ ๊ทธ๋ฆฌ๋ ์
์ ์์(์ฌ๊ธฐ์๋ ์์(hue)์ ๊ณ์)์ ๊ฒฐ์ ํ๋ f32 ๊ฐ๋ค์ ์ ์ฅํ๋ ๋ฒกํฐ์
๋๋ค.
grid_size: ํ์ฌ ๊ทธ๋ฆฌ๋์ ํฌ๊ธฐ (์: grid_size๊ฐ 8์ด๋ฉด 8x8 ๊ทธ๋ฆฌ๋)๋ฅผ ๋ํ๋
๋๋ค.
max_grid_size: ๊ทธ๋ฆฌ๋๊ฐ ๊ฐ์ง ์ ์๋ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ ํํฉ๋๋ค.
show_too_dense: ๊ทธ๋ฆฌ๋ ํฌ๊ธฐ๊ฐ ์ต๋์น๋ฅผ ์ด๊ณผํ์ ๋ "Too Dense" ๋ฉ์์ง๋ฅผ ํ์ํ ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ๋ถ๋ฆฌ์ธ ๊ฐ์
๋๋ค.
ํ๋ก๊ทธ๋จ์ ์ง์ ์ ์ ๋๋ค.
nannou::app(model).update(update).run(): Nannou ์ ํ๋ฆฌ์ผ์ด์
์ ์ค์ ํ๊ณ ์คํํฉ๋๋ค.
app: model ํจ์๋ฅผ ์ฌ์ฉํด ์ฑ์ ์ด๊ธฐ ์ํ๋ฅผ ์ค์ ํฉ๋๋ค.
update: update ํจ์๋ฅผ ๋งค ํ๋ ์๋ง๋ค ํธ์ถํ์ฌ ์ฑ์ ์ํ๋ฅผ ์
๋ฐ์ดํธํฉ๋๋ค.
run: ์ ํ๋ฆฌ์ผ์ด์
์ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์์ํฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฒ์ ์์๋ ๋ ํ ๋ฒ๋ง ํธ์ถ๋ฉ๋๋ค. 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 ๊ตฌ์กฐ์ฒด๋ฅผ ์ด๊ธฐํํ์ฌ ๋ฐํํฉ๋๋ค.
๋งค ํ๋ ์๋ง๋ค view ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ง์ ์ ํธ์ถ๋ฉ๋๋ค. ์ฑ์ ๋
ผ๋ฆฌ๋ฅผ ์
๋ฐ์ดํธํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
ํ์ฌ ์ฝ๋์์๋ ๋น์ด ์์ง๋ง, ์๋ฅผ ๋ค์ด "Too Dense" ๋ฉ์์ง๋ฅผ ํน์ ์๊ฐ ํ์ ์๋์ผ๋ก ์ฌ๋ผ์ง๊ฒ ํ๋ ๋ก์ง์ ์ฌ๊ธฐ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋งค ํ๋ ์๋ง๋ค ํ๋ฉด์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ ์ญํ ์ ํฉ๋๋ค.
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 ์ ๊ณต๊ฐ์ ์ด์ฉํด ์ค์ ํฉ๋๋ค.
0.8 (ํธ๋ฅธ ๊ณ์ด)๋ก ๊ณ ์ ๋์ด ์์ต๋๋ค.color_coefficient ๊ฐ (0.0 ~ 1.0)์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.0.4๋ก ๊ณ ์ ๋์ด ์์ต๋๋ค.if model.show_too_dense: show_too_dense๊ฐ true์ด๋ฉด ํ๋ฉด ์ค์์ "Too Dense"๋ผ๋ ํ
์คํธ๋ฅผ ํฐ์์ผ๋ก ๊ทธ๋ฆฝ๋๋ค.
draw.to_frame(app, &frame).unwrap(): ์ง๊ธ๊น์ง ๊ทธ๋ฆฐ ๋ชจ๋ ๋ด์ฉ์ ํ๋ ์์ ์ต์ข
์ ์ผ๋ก ๋ ๋๋งํ์ฌ ํ๋ฉด์ ํ์ํฉ๋๋ค.
ํค๋ณด๋ ํค๊ฐ ๋๋ ธ์ ๋ ํธ์ถ๋ฉ๋๋ค. 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๋ก ๋ฆฌ์
ํฉ๋๋ค.
_ => {}: ๊ทธ ์ธ ๋ค๋ฅธ ํค๊ฐ ๋๋ ธ์ ๋๋ ์๋ฌด ์์
๋ ํ์ง ์์ต๋๋ค.