Silverback9

#야생으로

Creative Coding 독학 제191일 2024년10월04일(금)

오늘은 이차원 배열 구조로 격자무늬를 시각적으로 표현해 보도록 하겠습니다~^^*

먼저, 어제 우리가 함께 자료구조적으로 이해해 본 이차원 배열 생성 함수 make2DArray(cols, rows)를 꺼내어 놓구요~^^*


function make2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}

//세로기둥 column의 갯수의 길이로 1차원 배열 arr가 생성됩니다. 
//각 세로기둥마다 칸 row의 갯수의 길이로 배열이 생성되어 담깁니다. 
//세로기둥 column의 갯수 길이의 배열의 구성요소들이 칸 row의 갯수 길이의 배열을 안에 각각 품고 있습니다. 
//최종적으로 arr[cols][row] 이차원 배열이 만들어 집니다. 

이차원 배열을 만드는 함수 make2DArray(cols, rows)에게 세로기둥 갯수 cols와 칸 갯수 rows을 매개변수 parameter로 전해주며 호출하여, 이차원 배열을 담을 수 있는 자료 저장구조를 생성한 후 변수 grid에 저장합니다.

let grid;
 
grid = make2DArray(cols, rows);

이차원 배열의 각 구성요소 arr[i][j]에 0 또는 1을 무작위로 생성하여 담아봅시다.


  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j] = floor(random(2));
      //random(2) : 0이상 2 미만 실수를 무작위로 생성한 후, 
      //floor() : 소수점 아래 부분은 버리고, 정수 부분만 취합니다. 
      //floor(random(2)) : 0과 1이 무작위로 생성되는 효과를 발휘합니다. 
      //생성된 0 또는 1을 이차원 배열 각 구성요소에 저장합니다. 
    }
  }

여기까지의 우리의 작업이 잘 이루어 지고 있는 지를 확인해 보기 위해, 이차원 배열을 시각적으로 표현해 볼까요~^^*

테스트를 위해, 세로기둥 column 10개가 칸 row 10개를 거느린 이차원 배열을 표현해 보겠습니다~

캔버스는 우리에게 친숙한 400 pixel * 400 pixel로 준비해 볼게요~^^*

너비 width가 400 pixel 인 캔버스가 세로기둥 column 10개로 나누어 지려면, 각 세로기둥 column의 너비는?

그렇죠! 400 pixel / 10 개 = 40 pixel이 되네요.

음…그럼, 40 pixel이 화면 너비의 해상도가 되는 것인가요? resolution?

높이 height가 400 pixel 인 캔버스가 칸 row 10로 나누어 지려면, 각 칸 row의 높이는?

네^^* 400 pixel / 10 개 = 40 pixel이지요~~^^*

40 pixel이 화면 높이의 해상도가 되는 것이네요? resolution?

와우!!!

해상도 resolution을 변화시키면, 화면의 세로기둥 column의 갯수와 칸 row의 갯수가 달라질 수 있겠네요?

Canvas / column = resolution => Canvas / resolution = column

음…그럼 우리….

세로기둥 column의 갯수와 칸 row의 갯수로 격자무늬 디자인을 결정하지 않고,

해상도 resolution으로 격자무늬를 디자인하면 어떨까요?

해상도 수치를 조절하면, 격자의 column과 row의 갯수가 조절되니까요^^*

let cols;
let rows;
let resolution = 40;


createCanvas(400, 400);
cols = width / resolution;
rows = height / resolution;

//해상도 40 pixel로 지정하여 
//400 pixel * 400 pixel 화면에
//세로기둥 column 10개 (400 / 40 = 10)
//칸 row 10개 (400 / 40 = 10)  

해상도 수치를 작게 하면 할 수록, 촘촘한 격자가 생성되겠네요~~^^*

세로기둥 column와 칸 row의 갯수를 신경쓰지 않으면서, 격자무늬 크기를 조정할 수 있어서 편리할 거 같아요~~^^*

이제 격자무늬를 시각적으로 표현해 볼까요?

격자배열 grid[][]에 0이 저장되어 있다면~ 아무 일도 하지 않기로 해요~

배경색 자체를 검은색으로 깔아 두고 있을 테니까, 아무 일을 한하면, 그 grid[][]의 공간이 검은 색 칸으로 보이게 될 것 같아요.

격자배열 grid[][]에 1이 저장되어 있다면~

격자무늬 한 칸 가득 들어가는 흰색 사각형을 만들어 볼까요~^^*

background(0);

for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      let x = i * resolution;
      let y = j * resolution;
      
      if (grid[i][j] == 1) {
        fill(255);
        rect(x, y, resolution, resolution);
      }
     //해상도 resolution 크기만큼 xy축 이동을 하며 격자무늬를 생성합니다.
     //해당 배열구성원의 정보가 0 이면 아무 일도 안합니다.
     //해당 배열구성원의 정보가 1 이면 해상도 크기의 흰색사각형을 그립니다. 

    }
  }

그럼 이제 전체 코드를 살펴 보고 격자 무늬도 구경해 볼까요~^^*



function make2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}

let grid;
let cols;
let rows;
let resolution = 40;

function setup() {
  createCanvas(400, 400);
  cols = width / resolution;
  rows = height / resolution;

  grid = make2DArray(cols, rows);
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j] = floor(random(2));
    }
  }
}

function draw() {
  background(0);

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      let x = i * resolution;
      let y = j * resolution;
      if (grid[i][j] == 1) {
        fill(255);
        rect(x, y, resolution, resolution);
      }
    }
  }

}

격자 무늬가 보이십니까~~~~^^*?

음…근데, 화면의 오른쪽 테두리와 아래쪽 테두리가…흰색 사각형 떄문에 끊어져 보이네요…

사각형의 기준은 왼쪽 위쪽 모서리이니까, 사각형의 너비와 높이를 1pixel씩 작게 하면, 검은 색 배경이 보여서, 마치 테두리를 두른 것 같을 것 같아요…한 번 해 볼까요?

fill(255);
rect(x, y, resolution - 1, resolution -1 );

어때요?

테두리를 좀더 확실하게 보여주면 어떨까요? 검은색 테두리를 둘러 볼게요~^^*

fill(255);
stroke(0);
rect(x, y, resolution - 1, resolution -1 );

화면 테두리가 좀더 자연스럽게 보이나요?

이번엔, 우리~~^^* resolution을 작게 만들어 아주 촘촘한 격자를 만들어 볼까요~^^*

let resolution = 10; 

아주 촘촘하지요~~~~~^^*

오늘 저와 함께 격자무늬를 표현하는 코드 파트를 완성해 주셔서 감사합니다~^^*

내일도 우리 또 만나서, Game of Life의 규칙에 대한 코드 공부를 함께 할까요~~^^*

작은 세포들이 모여서 생명체 활동을 함께 이루어 내듯이~~

코드 한 파트 한 파트가 모여서 하나의 프로그램으로 움직이는 것이 신기하고 재미있는 것 같아요!

우리가 하고 있는 작은 일들 작은 공부 작은 생활의 순간 한 조각 한 조각이 함께 모여 서로 유연하게 연결되면서 새롭고 재미있는 일과 공부와 삶을 구성하게 되는 것처럼요…

어머! 지금 까치가 울고 있어요^^*

시원한 공기와 까치 울음 소리와 창 밖의 노란 햇살이 함께 모여 유연한 나비 춤을 추면서 새로운 아침을 구성하고 있네요~~^^*

간단하고 쉬운 첫 단계도 즐거운 마음으로 함께 하면 아름다운 예술이 되어요~^^*

코딩 공부를 마치 예술 활동처럼 즐겁게 느낄 수 있도록, 저와 함께 공부해 주셔서 감사합니다~^^*

오늘도 멋진 아침! 멋진 하루! 보내시고요~~^^*

내일 우리 또 만나요~~^^*

네~~!!! 꿈은 이루어 집니다~~!!!

댓글 남기기