Jacquard Weave Algorithm 06

이를 간단한 code로 이해해보자. 반복하기 이전의 data를 A,B,C,D 라 가정하면 우리가 원하는 결과는 A,B,C,D,A,B,C,D 이다. 그러나 반복을 통하여 얻은 결과는 A,A,B,B,C,C,D,D 이다. 이를 해결해야만 우리가 원하는 algorithm을 완성시킬 수 있다. 개념적으로 여러 방법이 있는데 여기서는 data 의 tree structure를 재정렬(rearranging)하는 방법을 택하겠다.

<parameter viewer>를 이용하여 처음 네개의 data branch의 path number를 살펴보면 아래와 같은 순서를 가지고 있는 것을 알 수 있다.

{0;0;0;0;0;0}

{0;0;0;0;0;1}

{0;0;1;0;0;0}

{0;0;1;0;0;1}

그러나 우리가 원하는 path number의 순서는 아래와 같다:

{0;0;0;0;0;0}

{0;0;1;0;0;0}

{0;0;0;0;0;1}

{0;0;1;0;0;1}

즉 data branch의 순서가 위와 같이 정리된다면 pattern 전체를 반복시킬 수 있을 것이다. 이를 위해서는 먼저 위와 같은 순서를 가지는 path number를 생성해준뒤 data branch를 이에 맞춰 재정렬 해줘야 한다. 이를 위해서 먼저 path number를 생성하여보자.

Figure 29

Figure 29 우리가 얻어야 하는 path number는 위와 같다. 이를 살펴보면 일관되게 반복되는 0;0;외에 두 개의 수열이 있는 것을 알 수 있다.

  1. 첫번째 수열의 경우 그 값은 Y 방향의 cell의 수와 일치하고 이것의 반복 횟수(iteration)는 <Repeat_Y_(V)>에서 나오는 값과 일치한다.[1]
  2. 두번째는 수열의 경우 그 값은 <Repeat_Y_(V)>에서 정해진 반복의 횟수와 일치하고 이것이 반복되는 횟수는 Y방향의 cell의 수와 일치한다.[2]

Algorithm이 특별한 것은 아니지만 약간의 생각과 집중이 필요하다. 아래에서 보여지는 다음 단계는 위에서 생성한 수가 무엇을 의미하는지를 확실하게 보여줄 것이다.

Figure 30

Figure 30 먼저 세 개의<receiver>를 이용하여 canvas에 너무 많은 선이 그려지는 것을 피하도록 하자. 위 세 값은 앞으로 반복적으로 사용될 것이다. component의 이름을 위와 같이 바꿔 나중에 혼동되는 것을 방지해주도록 하자.

Figure 31

Figure 31 앞서 살펴본것 처럼 다섯 개의 다른 수를 생성하여 하나의 data list에 합쳐줘야 한다. 이때 모든 data는 string이 되어야 한다.[3] 첫 부분은 바로 ‘{0;0;’ 이다. 이를 <duplicate>해준다. 이때 그 수는 대상면에 적용되는 Y방향의 cell의 수 (target_srf_cell_Y)에 맞춰주도록 한다.

Figure 32

Figure 32 두 번째 부분은 <series>를 이용하여 생성해주도록하자. 먼저 수의 시작을 0.0, 등차를 1로하는 <series>를 불러온뒤 이것의 길이값’C’에 <Receiver_(Cell_No_Y_Fix)>를 입력해준다. 여기서 나오는 값은 실수(real number)이기 때문에 이를 <integer>에 연결하여 정수로 바꿔준 뒤 다시 이것을 <string>을 이용하여 문자 data로 바꾸어준다.  이것을 Y 방향으로 pattern이 반복되는 수만큼 반복시켜준다.

Figure 33

Figure 33 세번째 부분은 다시 ‘;0;0; ‘의 반복이다. 이것이 반복되는 수는 대상면에 적용되는 Y방향으로의 cell의 수와 같다.

Figure 34

Figure 34 네번째 부분은 다시 <series>로 생성해준다. ‘C’에 <Receiver_(Repeat_Y_(V))>에서 나오는 수를 입력시켜주도록 한다. 이를 다시 <integer>와 <string>을 이용하여 정수화, 문자화 시켜준다. 또한 <duplicate>를 이용하여 pattern image의 Y방향 cell의 수만큼 반복시켜주어야 한다. 이때 <duplicate>의 Boolean값인 ‘O’를 false로 입력해줘 0과 1이 반복되는 순서를 바꿔준다. [4]

Figure 35

Figure 35 string의 마지막 다섯번째 부분은 ‘} ’으로 이또한 대상면에 생성되는 Y방향의 cell의 수만큼 생성되면 된다.

Figure 36

Figure 36 이제 위에서 생성한 다섯개의 string data list를 하나로 합쳐줘야 한다. 이를 위해 사용 가능한 것은 원하는 수만큼의 변수를 줄 수 있는 <variable expression>이다. 이를 우클릭한뒤 input manager를 이용하여 입력되는 변수를 다섯개로 설정해준다. 다시 function을 a & b & c & d & x 로 설정해주고 각 data list를 입력해주면 위처럼 하나의 data list를 생성해준다.

이렇게 합쳐진 string data list의 결과는 아래와 같다.

Figure 37

Figure 37 결과를 살펴보면 우리가 원하는 순서대로 path number를 생성한 것을 알 수있다.

Figure 38

Figure 38 이제 앞서 생성한 vector amplitude값에서 나오는 각 data branch의 순서를<tree branch>를 이용하여 재정렬해준다. <tree branch>의 ‘P’에 위에서 생성한 path number를 입력해준다.

Figure 39 <tree branch>의 path에 string값이 입력되었다. 이제 우리가 생성한 geometry를 확인해보자.

Figure 40

Figure 40 재정렬된 data가 vector amplitude로 적용되었으며 이 값에 따라 점들이 <move>된 것을 확인할 수 있다. 위 image를 통하여 pattern을 확인하는 것이 다소 어렵지만 이전처럼 같은 형태를 가진 curve가 한 번 반복된 뒤 다음 curve로 넘어가는 것이 아니라는 것은 쉽게 확인 가능하다.


[1] 위 diagram은 대략적으로 그려진 것이다. 이 tutorial에서 Y 방향의 cell의 수는 16개이고 이것이 2회 반복된다. 각 data의 index number는 항상 0부터 시작하므로 이는  [0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11, 11,12,12,13,13,14,14,15,15]와 같다는 것을 알 수 있다. 이를 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15] 로 바꿔주어야 한다.

[2] 이또한 Y 방향으로 pattern이 2회 반복되는데 data의 index number는 항상 0부터 시작하기 때문에 [0,1]이 반복되는 것이다. 즉 우리가 원하는 결과는 [0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1, 0,1] 이다.

[3] Data type에 대한 자세한 설명은 다음 링크를 참고하기 바란다. http://en.wikipedia.org/wiki/Data_type

[4] 이 tutorial의 경우 Y방향으로 pattern image가 반복되는 횟수가 2이기 때문에 [0,1]이 반복된다. 이것이 만약 3이라면 [0,1,2]가 반복되어야 한다. 또한 <duplicate>의 경우 [0,1,2]가 입력되었을때 Boolean data가 (default 값인) true라면 [0,1,2,0,1,2]과 같은 형태로 반복된다. 이것을 false로 바꿔주면 [0,0,1,1,2,2]와 같은 형태로 <duplicate>된다. 이것을 쉽게 바꿔줄 수 있는 component로는 <Boolean toggle>이 있다.

Jacquard Weave Algorithm 05

_Data list를 matching 하기

지금까지의 algorithm에서 <image sampler>는 pattern image가 가진 cell의 수만큼만의 data를 생성하였다. 한편으로 우리가 대상면을 나눌때 이 cell의 수에 비례하여 나눌 수 있도록 algorithm을 짰기 때문에 이 data 또한 그에 맞춰 반복되어야 한다. 즉 점에 적용되는 point와 vector, 그리고 vector에 matching되는 amplitude값들이 모두 같이 반복되어야 한다.

아래 그림을 살펴보고 algorithm의 다음 부분에서 필요한 것들을 생각해보도록 하자.  <param viewer>를 통하여 각각의 값을 비교해보도록 하자.

첫번째 그림에서는 두 number slider의 값이 모두 1로 설정되어있다. <param viewer>는 16개의 data branch[1] (<cell_No_Y_Fix>에서 나오는 수와 같다.)가 있고 와 각각의 data branch에 17개의 data(<cell_No_X_Fix>에서 나오는 수와 같다.)

두번째 그림에서는 <number slider; Repeat_Y_(V)>의 경우 2로 설정되어있어 pattern을 Y 방향으로 반복하게 된다. 그 결과 data branch의 수는 두배가 되고 각 branch 안에 있는 data의 수는 그대로 유지된다.

세번째 그림은 이 전 단계와 반대이다. 즉 <number slider; Repeat_X_(U)> 가 2로 설정되어 있어 pattern을 x 방향으로 반복하고 있다. 그 결과 data branch의 수는 변하지 않지만 각 branch 안에 있는 data의 수는 두 배로 늘어나게 된다.

Image

Figure 24_1

Image

Figure 24_2

Image

Figure 24_3

Figure 24 _1.2.3 각기 다른 인수를 가지는 data structure의 비교

Image

Figure 25

위 세가지의 경우를 살펴보고 각각의 data list에 필요한 vector의 amplitude list를 비교해보도록 하자. Pattern을 X방향으로 반복하면 각 branch 내의 data들이 그안에서 반복되어야 하며, Y방향으로의 반복에선 Y방향으로 있는 모든 data branch가 반복되면서 각 branch 안에서의 data들은 변하지 않은채로 남아있어야 한다. 이러한 개념을 구현하기 위해서는 data management에 사용되는 컴퍼넌트를 algorithm에 적용시켜줘야 한다.

Figure 25 Pattern이 각기 방향으로 반복되는 횟수를 결정하는 두 slider의 역할이 매우 중요하다. 둘 다 <receiver> 에 연결되어 data가 복제되는 수를 결정하게 된다.

Image

Figure 26

Figure 26 이전에 생성한 Vector의 amplitude의 경우 그 data list가 <number slider; repeat_X_(U)> 에서 나오는 수만큼 복제된다. <Param Viewer>에서 본 것처럼, data branch 의 수는 <duplicate>가 되기전처럼 그대로 16개 이지만 각 data branch 내부에 있는 data들의 수는 변해있다. 즉 pattern image를 X방향으로 반복시키는 횟수를 정해줄때는 vector의 amplitude 또한 이에 상응하여 변해야 한다는 것을 의미한다.

Image

Figure 27

Figure 27 X방향으로 data를 복제할때는 <duplicate>를 사용했지만 이번에는 <repeat>을 사용해야한다. Data branch를 통째로 복사해줘야 하기 때문이다. 이 algorithm에서 다소 까다로운 부분은 바로 <repeat>의 input 값인 ‘L’을 결정하는 것이다. ‘L’은 최종 결과물의 길이와 같아야 하므로 이것이 각 data branch에 들어있는 data들의 수와 일치하여야 한다. 이는 X방향으로 data를 반복시킬때 사용한 <duplicate>에 <list length>를 적용하면 된다. 이때 이 list length의 값 또한 pattern image가 Y방향으로 반복되는 수만큼 반복되어야 한다. 그러므로 <epeat_Y_(V)>에서 나오는 값만큼 <list length>를 <duplicate>해준다. (이 tutorial에선 두 번 반복되었다.) 이제 두 <duplicate>에서 나오는 값을 <repeat>에 적용시켜고 <parameter viewer>를 확인해보면 우리가 원하는 만큼 data branch의 수가 복제된 것을 알 수 있다.

즉 X 방향으로 data를 반복할때는 각 data branch 안에서 data가 반복된 것이고 Y방향으로 반복시킬때는 data branch 전체가 반복된 것이다.

<parameter viewer>를 통해 우리가 원하는 수만의 data가 복제되는 것을 확인하면서 다 끝났다고 생각할지모르겠다. 그러나 아직 풀어야할 문제가 있다. 어떤 문제인지 확인하기 위해 모든 점들을 위에서 생성한 값(즉, vector amplitude) 만큼 값으로 이동시고 <interpolate curve>가 어떤 결과를 그려내는지를 확인해보자.

Image

Figure 28

Figure 28 <repeat>에서 나오는 값을 <amplitude>의 ‘A’에 입력한다. 결과물을 보면 X방향으로의 반복의 경우 우리가 원하는대로 된 것을 확인할 수 있으나 Y방향의 경우 pattern image가 하나의 단위가 되어 전체적으로 반복되는 것이 아닌, 각 씨실(x방향으로 있는 curve)이 반복된 것을 볼 수 있다.


[1] 저자의 경우 paths of data 와 branch of data를 혼용하였지만 이 번역본에서는 모두 data branch로 표현되었다.

Jacquard Weave Algorithm 04

3_3_4_Weaving Target surface by Pattern

Algorithm의 첫 번째 부분에서 사용한 <image sampler>는 우리가 준비한 pattern image를 각 cell의 밝기(brightness)정보에 근거하여 수치정보로 전환시켰다.  이는 pixel이 검은색인가 흰색인가에 최종적으로 직조되는 실이 어떤 지점에서 대상면의 위에 있고 어떤 점에서 아래로 가야하는지를 결정하게 된다. 두 번째 부분에서는 대상면을 나눈 sub-surface를 pattern image의 cell의 수와 비례하게 구한 뒤 각 sub-surface들의 중심점과 그 지점에서의 normal vector 값을 구하였다.

즉, 첫번째 <image sampler>에서 구한 값을 우리가 두번째 부분에서 찾아낸 normal vector의 <amplitude>값으로 입력하여 대상면 위에서 점의 이동 방향과 정도를 결정해주는 것이다. 이를 위해서는 먼저 data를 어떠한 방식으로 구조화 할 것인지에 대한 고민이 필요하다.

 

Figure 19


Figure 19 <image sampler>에서 나오는 값들을 살펴보자. 위 그림에서 초록색으로 변한 <panel>을 살펴보면 각 branch에 들어있는 data들이 이들이 모두 하나의 실수를 가지고 있다는 것을 알 수 있다. 다시 살펴보면 이들은 거의 대부분 0이나 1에 수렴할 뿐 0이나 1이 아님을 알 수 있다. (예를 들어 0.02, 0.004, 0.996, 0.988 등) 이는 몇 pixel의 경우 그 밝기가 data 적으로 완벽한 검은색(RGB: 0,0,0)이나 흰색(RGB: 255,255,255)으로 인식되지 않기 때문이다. Pattern을 명확하게 하기 위해서는 이를 0과 1로 고쳐주어야 한다.

 

Figure 20


Figure 20 <f1; round(x)>를 이용하면 x로 입력되는 값을 반올림을 해줄 수 있다. 이를 이용하여 모든 값들을 0 혹은 1로 바꾸어 줄 수 있다.

<image sampler>에서 추출된 값(evaluated value)들은 normal vector의 <amplitude>에 적용되어야 한다. 이때 vector의 방향값이 ‘양수(+)’인지 ‘음수(-)’ 인지에 따라 최종 결과물에서 모델링된 ‘실(yarn)’이 대상면의 각 지점에서 면의 위에 있는지 혹은 아래에 있어야 하는지가 결정된다. 이 말은 만약 vector의 길이(magnitude)가 어떤 지점에서 +2.345 라고 한다면 실의 기본이 되는 <interpolate curve>가 대상면의 해당 지점에서 2.345만큼 ‘위에’[1]있게 되는 것이다. 반대로 -2.345라면 해당 지점에서 2.345만큼 ‘아래’있게 되는 것이다. 이 vector의 방향값중 절대값을 parameter화 하여 designer가 원하는 만큼 입력하게 해주고, 그것의 부호를 pattern image의 흑과 백으로 결정해주면 된다.

 

Figure 21


Figure 21 위에서 말한 것 처럼 <image sampler>는 normal vector가 양수값을 가질 것인지 음수값을 가질 것인지를 결정해주어야 한다. 그러기 위해서는 앞서 구한 0과 1의 data list를 0은 -1로, 1은 1로 변환시켜주어야 한다. 이는 간단한 함수의 적용을 통해 구할 수 있다. <f1; (x+x)-1> 을 이용하면 0은 -1로, 1은 1로 변환되게 된다. 이로서 pattern image의 흑과 백에 의거하여 normal값의 vector를 구할 수 있게 되었다.

X=1 -> F(X)=(1+1)-1= +1

X=0 -> F(X)=(0+0)-1= -1

 

Figure 22


Figure 22 이제 vector의 강도, 즉 pattern의 ‘파동(corrugation)‘의 정도는 위와 같이 구할 수 있다.

 

Figure 23


Figure 23 <image sampler>로 부터 생성된 vector의 ‘강도값(amplitude)’


[1] Rhino에서 그린 면이 위로 향하고 있는지 아래로 향하고 있는지, U,V방향이 절대좌표의 x,y 축과 일치하는지에 따라 그 결과물이 달라질 수 있다. 이를 방지하기 위해서는 꼭 dir 커맨드를 이용하여 대상면의 normal 방향과 UV 방향을 확인하고 원하는 것으로 바꾸어 주도록 하자.

Jacquard Weave Algorithm 03

3_3_3_대상면에 기준점 그리기

 

Figure 12


Figure 12 이제 rhino에 그려진 surface를 grasshopper의 <surface>를 이용하여 canvas로 불러오도록 하자. <surface>의 이름을 <Target_srf> 로 바꿔주도록 하자. 나눠진 면(Sub-surface)을 생성하기 위해서는 이 <Target_srf>에 <SubSrf> 를 연결해주어야 한다.

나눠진 면(sub-surface)를 생성할 때는<divide domain2>를 사용해야 한다. 이때 대상면을 먼저 v방향으로 나누어야 하는데 이를 위해서는 <divide domain2>의 ‘U’를 ’1’로 해주어야 한다. <integer>를 이용하여 U에 ‘1’을 넣어주도록 하자. V 방향으로 나누는 횟수를 생성하기 위해서는 먼저 두 개의 인수가 필요하다. 먼저 대상면은 적어도 pattern image의 Y방향에 있는 cell의 수만큼 나누어 져야 한다. 이를 위해서는 전장에서 생성했던 <Receiver_(Cell_No_Y_Fix)>[1]로 부터 data를 끌어온다. 이때<multiplication>을 사용하여 <number slider; Repeat_Y_(V)>를 이용 나뉘는 반복의 횟수를 제어해줄 수 있다.

 

Figure 13


Figure 13 <Target_Srf>가 V방향으로 나눠지는 수를 <number slider; Repeat_Y_(V)>를 이용하여 designer가 원하는 만큼 제어해줄 수 있다. 가장 왼쪽은 pattern이 한 번 반복 된 것이다. 그 다음은 두 번 그 다음은 세 번 반복된 것이다.

 

Figure 14


Figure 14 다음으로, 앞서 V 방향으로 나뉘어진 surface들을 다시 U 방향으로 나누어 주어야 한다. 이를 위해서는 위에서 한 것처럼 다시 <SubSrf>와 <divide domain2>을 사용해야 한다. 마찬가지로 전장에서 생성한 <cell_No_X_Fix>로 부터 data를 끌어와 최소 횟수를 만들어 준 뒤 designer의 의도만큼 반복할 수 있도록 <number slider; Repeat_X_(U)>를 <multiplication>하여준다. 이 때 이렇게 U와 V 방향으로 나누어진 결과물을 <Param Viewer>에 연결하면 U, V 방향으로 나누어진surface의 data가 각 branch에 나누어 저장된 것을 확인할 수 있다.

 

Figure 15


Figure 15 X와 Y 방향 (surface 상에서는 U와 V 방향)으로 나누어진 면이다. 위 그림처럼 각 횟수를 제어해줄 수 있다.

이제 이렇게 UV 방향으로 나누어진 sub-surface가 준비되었다. 각 sub-surface 위에서 기준점을 추출해보자. 각 sub-surface가 pattern image에서 하나의 cell과 동일하다는 것을 고려하였을때[2] 추출점은 sub-surface의 중심점(mid-point)이 되어야 한다.

 

Figure 16


Figure 16 중심점을 찾기 위해서는 <Area>를 사용할 수 있다. 이는 면적의 계산값 A와 중심점C를 출력한다. 이 점을 다시 <Surface CP> 에 연결하고 여기서 얻어진 점의 UV좌표밗을 이용하여 다시 <evaluate surface>를 해준다. 이를 통하 각 점에서 sub-surface들이 가지는 ‘Normal’값을 추출할 수 있다.

 

Figure 17


Figure 17 이제 이렇게 얻어진 각 중심점들을 normal vector를 이용하여 <move>해준다. <display vector>를 이용하여 확인해볼 수 있듯이 각 ‘normal vector’들은 모두 같은 방향을 가지고 있다. 즉 현상태로는 아무런 ‘파동 (corrugation)’을 생성할 수 없다. 여기에 <Amplitude>를 이용하여 vector의 방향값에 길이를 조절해줄 수 있다. (이때 길이에 양수와 음수를 넣어주면 방향을 바꾸는 것도 가능하다.)

 

 

Figure 18


Figure 18 이 부분은 전체 algorithm에서 대상면을 필요에 맞게 자르는 역할을 하게된다.


[1] 해당 컴퍼넌트는 현재 grasshopper 버전에서는 삭제되었다. 직접 연결해주거나 중간에 <data>를 이용해줄 수 있다.

[2] 해당 tutorial에서는 반복 횟수가 정의된 <number slider>는 1로 고정되어 있기 때문이다.

Jacquard Weave Algorithm 02

3_3_2_직조pattern이 적용되는 객체 만들기

수치 data로 환원시킨 직조 pattern을 target surface 에 적용시켜보도록 하자. 이때 target surface는 최종 결과물로서 pattern이 입혀지는 적용면(target surface)가 된다. 이를 이해하기 위해서 첫번째 장에서 만들었던 직조 패턴(loom algorithm)을 다시 떠올려보자. 이번 algorithm도 이와 마찬가지로 주로 세 단계로 나눌 수 있다.

첫번째는 먼저 적용면에서 원하는 위치에 point grid를 생성해준다. 두 번째로 각 점을 원하는 pattern에 맞게 아래, 위로 이동시켜 준다. 세번째로 각 점을 통과하는 curve를 그려주면 된다. 이 curve는 후에 실(yarn)을 만드는데 사용된다. 이 과정을 위해서는 다음과 같은 고려가 필요하다.

 

  1. 가장 중요한 것으로 pattern의 scale을 적용면의 scale에 맞추는 것이다. 즉 pattern을 적용할때 다양한 scale로 적용하는 것이 가능하기 때문이다.

 

 

Figure 10


Figure 10 적용면(target surface)과 pattern. 적용면은 algorithm의 input으로 나중에 pattern이 적용되게 된다.

 

Figure 11_1


Figure 11_2


Figure 11 원하는 pattern에 맞추어 적용면을 직조하기 위해서는 먼저 pattern이 적용되는 scale을 정해야 한다. 이는 원하는 결과물에 따라 달라질 수 있다. 즉 하나의 pattern을 적용면아 반복하여 적용해주는 것인데 이 때 적용면을 나누는 수를 parameter화 해주면 후에 scale을 조절해줄 수 있다.

위의 다이어그램 처럼 먼저 pattern을 대상면에 적용한 뒤 이것이 대상면의 U, V 방향으로 얼마나 반복되는 지를 algorithm을 통해 정해줄 수 있다.

 

  1. 다음으로 중요한 것은 pattern이 mosaic처럼 분리 가능한 module로 적용될 수 없다는 것이다. 즉 morphing과 같은 방식의 algorithm을 적용할 수 없다는 것이다.[1] 최종 결과물이 되는 실(yarn)은 curve를 piping 하는 것이기 때문에 각 열과 행의 curve는 각각 독립된 객체가 되어야 한다. 앞서 생성한 point grid의 각 열을 tree data를 이용하여 branch 로 분리해준 것은 위와 같은 이유이다.

 

  1. 만약 pattern의 반복에 mirror를 이용한다면 이 또한 algorithm에 포함해줄 수 있다. (이번 tutorial에서는 사용되지 않는다.)


[1] 역자 주 https://geometricmind.wordpress.com/2011/03/20/generative-algorithm-030/ 를 참고하자. Morph를 이용하면 pattern이 module화 되어 적용된다. 해당 tutorial 에서는 원하는 결과이 직조인 만큼 씨실과 날실이 연속하여야 한다.

Jacquard Weave Algorithm 01

_직조의 원리를 Grasshopper에 적용하기

<image sampler>를 이용하면 grasshopper로 각종 image를 쉽게 불러드릴 수 있고 이를 수치 data로 환원시킬 수 있다. 이는 특히 특정한 pattern을 가지는 image를 수치 data로 변환시키는데 매우 유용하다. 이 방법에 대해서 알아보도록 하자.

Figure 1


Figure 1 <Image Sampler>는 이미지를 수치 data로 변환시킬 수 있다.

<Image Sampler>는 image와 좌표값을 input으로 가진다. 주어진 image의 해당 좌표에 있는 pixel의 색정보를 추출(evaluate)하는 기능을 가지고 있다.[1] 예를 들어 격자로 배열된 점의 좌표값이 주어지면 이미지에서 주어진 좌표값에 해당하는 pixel에서 정보를 추출하는 것이다. 특히 흑백이미지(grayscale)는 픽셀이 하얀색과 검은색으로 구성되어있기 때문에 이러한 정보를 쉽게 활용할 수 있다. 이때 흑백이미지에 있는 pattern의 각각의 cell의 중심점을 사용하는 것이 중요하다. 위에서 소개한 pattern imager의 경우 cell이 격자형태로 배열되고 각 cell이 흑, 백의 data를 가지게 된다. 이때 하나의 cell은 다시 여러개의 pixel로 구성된다.

그러므로 이러한 algorithm 에서 가장 먼저 필요한 것은 data를 추출하고픈 pixel의 좌표값을 생성하는 것이다. 이것을 <image sampler>를 이용하여 image에 적용하면 해당 pixel의 정보를 얻을 수 있다. 이때 각 cell의 중심에 있는 pixel을 고르는 것이 중요하다. 그렇지 않으면 원하지 않는 정보가 입력될 수 있기 때문이다.

Figure 2


Figure 2 <Image Samping>을 사용할때 추출점을 각 픽셀의 중앙에서 취하도록 조절해야 한다. 그렇지 않으면 원하지 않는 데이터가 입력될 수 있다. 흑백으로된 pattern image를 사용하면 무척 유용하다.

 

Figure 3


Figure 3 Source Image를 확대해보면 픽셀의 사이에 흑과 백이 아닌 중간톤의 색을 가진 영역을 찾을 수 있다. 이번 algorithm에서는 흑, 백의 정보가 필요하기 때문에 정확한 좌표값 input을 통하여 이러한 점을 피해주는 것이 중요하다.

 

 

 

_<Image Sampling> Process를 위한 점 생성하기

샘플로 사용될 점을 생성하기 위해서는 먼저 격자로 배열된 점이 필요하다. 행(row)에 들어가는 점의 개수와 열(column)에 들어가는 점의 개수가 Sample Image에서 각 방향에 cell의 수와 일치하여야 한다. 각 점들사이의 거리를 알기 위한 가장 쉬운 방법은 image의 가로 세로 방향의 크기(resolution)을 알아낸 뒤 이것을 각 cell의 pixel의 수로 나누어 주는 것이다. 먼저 이미지의 가로 방향 pixel의 수를 <Image_size_x_pixel>에, 새로방향 pixel의 수를 <Image_size_y_pixel>에 너어주도록 하자.

 

Figure 4


Figure 4 Image의 x,y방향의 pixel의 수와 각 cell의 pixel 수를 직접 입력하였다. (x는 image의 너비를, Y는 image의 높이를 의미한다.) 이를 <division>을 이용하여 나누어 주면 cell의 개수를 생성할 수 있다. 여기서 경우에 따라 소수값이 나올 수 있는데 이를 다시 <f1 ; fix(x)>에 연결하여 결과값을 정수로 만들어준다.

이때까지 생성한 정보들을 이용하여 point grid를 생성하도록 하자. 앞서 언급한 것처럼 각 cell의 중심에 점을 위치시켜야 한다. 그러기 위해서는 점의 격자에서 첫번째 점[2]의 위치가 각 cell의 pixel수의 절반 값이어야 한다. <Cell_size_x_pixel>, <Cell_size_y_pixel>에 입력된 cell의 가로, 새로 방향 pixel 정보를 <f1 ; x/2>에 연결하여 값을 반으로 나눈다. 이 값은 후에 만들어질 point grid의 첫번째 점이 된다. 다시 <f1 ; x/2> 에서 나온 값을 각각 <Image_size_x_pixel>, <Image_size_y_pixel> 에 입력된 Image의 전체 가로 세로 픽셀 수에서 빼주준다. 이렇게 나온 좌표값은 point grid의 마지막 점[3]의 좌표가 된다. 첫번째 점과 마지막 점의 x 좌표를 구간으로 하는 <domain>을 만들어준다. 이 값과 <f1 ; fix(x)>에서 구한 값에 <f1 ; x-1>을 적용한 값[4]을 <range>에 입력하면 필요한 x 좌표값을 생성할 수 있다. 같은 방법으로 Y방향의 좌표값도 생성해주도록 하자.

 

Figure 5


Figure 5 이제 이렇게 만들어진 <domain>을 <range>에 입력하고 cell의 개수에서 1을 뺀 값으로 나누어 준다. 만약 cell의 개수에서 1을 빼주지 않으면 필요한 값의 수보다 하나를 더 가지게 되기 때문이다. 이렇게 하면 point grid를 생성하는데 필요한 x, y 좌표값을 구할 수 있다. 물론 <series>를 이용하면 더욱 쉽게 algorithm을 완성할 수 있지만 정확도가 떨어지게 된다. 이를 방지하기 위해서라도 위와 같은 방법을 취하도록 하자.

 

Figure 6


Figure 6 x 방향의 좌표값을 가지는 <range>와 y 방향의 좌표값을 가지는 <range>를 <XYZ point>의 X와 Y값에 입력해준다. 이때 y좌표값은 <graft>를 이용하여 tree 구조로 변환시켜준다.  이렇게 되면 같은 y값을 가지는 data들이 하나의 branch 안에 저장되며 각 branch에는 x방향에 있는 cell의 수와 같은 점들이 생성되게 된다. 즉 Image에서 각 행(row)방향, x방향에 있는 cell들이 씨실(weft)의 굴곡을 결정하게 되는데 이 정보가 하나의 branch안에 저장되는 것이다.

 

Figure 7


Figure 7 이미지 샘플링을 할때 반드시 해야하는 것 중 하나이다. <image sampler>를 우클릭하여 context pop-up menu를 불러온 뒤 이것을 이용하여 import된 이미지의 x, y domain을 입력해주어야 한다. 만약 이 domain이 설정되지 않으면 출력되는 data가 Null 값이 되게 된다.

 

Figure 8


Figure 8 Grayscale로 된 image를 사용할때는 <image sampler>의 filter를 ‘Value’로 설정해주어야 한다. 그냥 Colour로 둘 경우 R, G, B 값을 출력하기 때문이다. 이 algorithm에서 색은 의미가 없으므로 image에서 밝기(brightness)만 취해주면 된다.

 

 

Figure 9


Figure 9 직조 pattern (weaving pattern)을 가지는 image에서 algorithm에 필요한 data를 추출하였다.

 

 

 


[1] <역자 주> 이때 추출되는 정보는 설정된 filter에 따라 여러가지로 변환될 수 있다. 기본적으로 0~255에 해당하는 R,G,B 값을 추출할 수 있으며 ‘투명도(transparency)’와 ‘밝기(brightness)’를 추출하는 것이 가능하다.

[2] 역자 주: 첫번째 점이란 점의 (x,y) 좌표값를 기준으로 그 값이 가장 작은 점을 의미한다.

[3] 역자 주: 마찬가지로 마지막 점이란 점의 (x,y) 좌표값이 가장 큰 점을 의미한다.

[4] 역자 주: cell의 수보다 1이 작은 수로 <domain>을 나눠야 cell의 수와 일치하는 수의 좌표값을 생성할 수 있다. <divide curve>에서 curve를 5등분 하면 여섯 개의 점이 생기는 것을 생각해보자.

Multivariable Calculus Surface Generator for Lec 9 | MIT 18.02

Grasshopper Definition

The grasshopper definition is to come up with visual clues of surfaces covered by one of MIT open lecture series ‘multivariable calculus’. ‘Multi’ here actually means 2, and I had to add a scale factor for z-axis to control the look of the resulted surfaces. Images below are some examples.

1/20*(x^2-y^2)

1/20*(x^2+xy-y^2)

The lecture is available on youtube.

직조(織造)알고리즘 (The Loom Algorithm)

본 번역은 원작자인 Zubin M Khabazi 와의 합의에 의해 이루어진 일입니다. 번역과 동시에 연재의 형식으로 포스팅 될 것입니다. 번역이 모두 끝나면 pdf 형식으로 합본을 배포하게 될 것입니다. 번역에 모자라는 부분이 있다면 댓글 형식으로 수정을 제안해주시기 바랍니다.

 

알고리즘을 시작하기에 앞서 전반적인 과정과 이에 필요한 data들을 살펴보도록 하자. 먼저 알고리즘의 input이 될 NURBS곡면이 있어야 한다. 이 위에 날실은 U 방향으로, 씨실은 V방향으로 생성될 것이다. 이 날실과 씨실들은 싸인 그래프의 곡선과 같은 형태를 가질 것이며 이러한 곡선을 그리기 위해서는 그것의 인풋이 되는 점들이 필요하다. 이 점은 번갈아가며 면의 위 아래로 이동하여 연결될 것이며 이때 점이 이동하는 방향으로는 각 점에서 input surface가 가지는 법선벡터와 그 반대 방향을 취할 것이다.

 

  1. 날실이 면 위의 점에서 시작한다면 그 옆의 날실은 면 아래의 점에서 시작해야만 한다. 이는 씨실도 마찬가지이다. 그래야만 파동형의 선이 번갈아가서 생기며 교차하며 면을 만들 수 있다.

 

  1. 면 위의 한 점을 이동시킬 때 법선의 방향으로 +A 만큼 이동시킨 점을 날실이 지난다면 –A 만큼 이동시킨 점은 씨실이 지나야 한다. 혹은 이 반대가 되어야만 면을 생성시킬 수 있다.

 

위와 같은 개념에 기초하여 Grasshopper에서의 알고리즘은 다음과 같이 생성될 수 있다.

Fig.2 4 위에서 언급한 것처럼 알고리즘을 시작하기 위해서는 먼저 결과물의 전체적인 형상을 결정할 ‘NURBS 곡면’이 필요하다. 이를 위해서 <surface>를 이용하여 Rhino상의 곡면을 Grasshopper에 연결시켜 준다. 이것의 이름을 <Target_surface>로 변경하였다.
 
 

Fig.2 5 <Subdivide>를 이용하여 <Target Surface>를 원하는 씨실과 날실의 수만큼 나누어 준다. 이 때 <input>이 되는 수를  <number slider>를 이용하여 입력하여 주자.[1] <Subdivide>을 이용하면 면이 UV수로 나눠져서 생긴 점(P: point)들과 그 점들에서 생긴 면들의 법선(N: normal) 그리고 각 점들의 UV 좌표값(UV: UV coordinates)을 얻을 수 있다.[2]
 
 

Fig.2 6 위에서 언급한 것처럼 파동형의 날실과 씨실을 만들기 위해서는 면에 생성된 점들을 면의 아래 위로 이동시켜야 한다. 이를 위해서는 같은 절대값을 가지는 음수와 양수가 하나씩 생기는 수의 data list가 필요하다.  <F1:-x>을 이용하여  <corrugation_height>에서 나오는 값을 음수로 만든 뒤 이 둘을 <weave>에 연결해주면 두 값을 하나의 data list로 묶어줄 수 있다.
 
 
 

2_3_1_날실의 생성(Warp Generation).

 

Fig.2 7 날실의 생성(Warp Generation). <Repeat>은 말 그대로 이것에 입력되는 data를 반복하여 생성해주는 것이다. <weave>에서 나오는 양수와 음수의 data list를 연결하여 이것을 씨실(weft)의 수만큼 반복 생성시켜주자. (날실을 생성하는데 사용되는 점의 수는 씨실의 수와 일치하기 때문이다.) 이 값을 <amplitude>를 이용하여 각 점이 가지는 법선(normal)값과 data matching을 시켜준다. <amplitude>는 ‘벡터(V: vector)’에 입력벡터를 ‘강도(A: amplitude)’에 입력된 값만큼의 크기로 변환해준다. 이것을 <move> 연결하면 면 위의 점들 원하는 만큼 이동시켜 줄 수 있다. <repeat>에서 나오는 값을 <F1: -x>를 이용하여 변환시킨 뒤 또 하나의 <amplitude>와 <move>에 입력시켜준다.
 
 

Fig.2 8 모든 점들이 면의 아래 위로 이동한 것을 확인할 수 있다. 이 때 두<move> 중에 하나를 선택하면 점이 어떻게 이동하였는지를 확인할 수 있다. 두 <move>가 각기 따로 아래 위로 점을 이동시켰다.
 
 

Fig.2 9 이렇게 <move>가 된 점들을 <interpolate curve>에 연결하면 같은 위치에서 mirror된 것처럼 보이는 곡선을 생성할 수 있다. 이제 이 두 선들을 <cull>을 이용하여 하나씩 번갈아서 선택하여 주자.
 
 

Fig.2 10 이 때 주의해야 할 것은 <interpolate curve>에서 생성된 data list는 트리구조를 가지고 있다는 것이다. 이를 <Param Viewer>를 통하여 확인할 수 있다. <cull>을 하기 위해서는 이 data list의 트리구조를 없애고 모든 data를 하나의 list 안에 정렬시켜주어야 한다.[3] 이러한 기능을 가진 것이 <flatten>이다. 이제 <cull>에 입력되는 Boolean data의 패턴(P: pattern)을 편집하여 주자.[4]
 
 

Fig.2 11 완성된 ‘날실의 생성(warp generation)’ 알고리즘

 
 
 

2_3_2_씨실의 생성(Weft Generation)

 

Fig.2 12 이 다음으로는 씨실을 생성해줘야 한다. <Subdivide>에서 생성되는 data가 U방향으로 생성되므로[5] 씨실을 생성하기 위해선 이것의 방향을 V방향으로 바꿔줘야 할 필요가 있다. 여기서는 이러한 문제를 해결할 수 있는 방법 중 가장 쉬운 것을 소개하겠다. 먼저 rhino상에서 그려진 <Target_Surface>를 같은 위치에 복사에 넣은 뒤 이것의 UV 방향을 바꿔주면 된다. 이를 하기 위한 과정은 다음과 같다.
 
1. <Target surface>를 선택한다.
 
2. 아래와 같은 순서로 명령어를 입력해준다.
 

      Copy (enter)

      I (enter)

      Dir (enter)

      S (enter)

      (enter)

 
이는 먼저 선택된 surface를 복사(copy)한 뒤 같은 위치에 (i) 만들어주고, 이것의 UV방향을 돌려준(s: swapping)해준 것이다. 이러면 같은 surface의 UV 방향만을 바꿔줄 수 있다.
 
3. 이제 이렇게 생성된 rhino상의 surface를 Grasshopper에서 <surface>와 연동시킨 뒤 <Swap: UV_Target_surface>로 명명해준다.[6]
 
 

Fig.2 13 여기서 또한 surface가 <subdivide> 된다. 이 때 <swap: UV_Target_surface>는 <Target_surface>의 UV 방향을 바꾼 것이므로 <subdivide>의 U(U: u direction)에 씨실(weft)의 수를, V(V: V direction)에 날실(warp)의 수를 연결시켜주어야 한다. 나머지 알고리즘은 ‘날실의 생성(Warp Generation)’ 알고리즘과 일치한다.
 
 

Fig.2 14 씨실과 날실의 생성에 사용된 알고리즘은 모두 같다.
 
 

Fig.2 15 이때 <cull>의 P에 입력되는 Boolean data를 위와 같이 바꿔주자. 모든 설정을 마치면 왼쪽 그림과 같은 결과를 얻을 수 있다.
 
 

Fig.2 16 이제 거의 마지막이다. <number slider>를 이용하여 이렇게 생성된 씨실과 날실의 곡선들에 적용할 두께 값을 설정해주자. 이것을 <Yarn_Thickness>로 명명하였다.
 
 

Fig.2 17 <cull>에 의해서 솎아낸 씨실과 날실의 곡선들을 모두 <pipe>에 연결해주자. 물론 씨실과 날실을 각각 다른 <pipe>에 연결하여 다른 두께 값을 주는 것이 가능하다.
 
 


Fig.2 18 직조 알고리즘을 이용한 Digital Textile의 생성 ‘평직(平織: plain weave)’,
 
 


[1] 역자 주: 해당 tutorial에 사용된 <receiver>는 0.8.0010버전 이후의 grasshopper에서는 존재하지 않는다.
[2] 역자 주: 0.8.0010버전에서는 <Subdivide>의 S를 우클릭 한 뒤 이를 ‘reparameterize’를 해야 UV 좌표값을 얻을 수 있다.
[3] 역자 주: 트리구조를 가지는 data에 관한 자세한 내용은 generative algorithm 의 5_6_On Data Trees 를 참고하기 바란다.
[4] 역자 주: P를 우클릭 한 뒤 ‘manage boolean collection’을 선택하면 Boolean data를 편집하여 줄 수 있다. 이 때 true와 false는 영문으로 입력해줄 수도 있고 false를 의미하는 ‘0’이나 true를 의미하는 ‘1’을 입력해줄 수도 있다.
[5] 역자 주: Grasshopper에서 생성되는 data는 일반적으로 U 방향으로 그 순서를 유지하며 생성된다. 이것의 방향을 바꾸기 위해선 매우 복잡한 과정을 거쳐야 하는데 이 튜토리얼에서 저자는 rhino의 input을 조절하여 매우 쉽게 이 문제를 해결하고 있다. 이처럼 어떠한 결과물을 그릴 때 rhino에서 input되는 기하체와 grasshopper에서 만들어지는 algorithm 둘을 적절하게 섞어서 만드는 것이 무척 중요하다.
[6] 역자 주: 날실을 생성하는 알고리즘을 모두 복사한 뒤 그것에서 <Target_surface>의 이름만 변경해주면 된다. 이 때 처음에 같은 절대값의 음수와 양수를 반복 생성하는 <F1: -x>과 <weave>는 공유하여 씨실과 날실이 같은 진폭(amplitude)를 가질 수 있도록 하자.