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등분 하면 여섯 개의 점이 생기는 것을 생각해보자.

직조(織造)알고리즘 (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)를 가질 수 있도록 하자.

Generative Algorithm 040

두께 주기(Generating Ribs)


이렇게 재배열 된 section curve들에 뭔하는 만큼의 두께를 주도록 하자. 먼저 <offset>을 이용하여 curve를 원하는 만큼 <offset> 시킨다. 원래 curve와 <offset> 된 curve의 각 양끝을 찾은 뒤 이것에 <line>을 더하여 이어준다. 이러면 원하는 두께를 가진 구조체가 완성된다. 위와 같은 과정을 다른 방향으로 생성한 section curve에도 적용시켜 준다.

Generating Joints (Bridle Joints)

다음 단계로는 이 구조체들이 서로 얽힐 수 있도록 교차되는 부분을 반씩 파주는 것이다. 

여기서 사용된 다른 방향의 plane은 위에서 그린 plane이 아닌 저자가 새롭게 따로 그린 plane 이다. 이 plane이 input surface와 만나며 curve를 생성하게 된다. [1] 는 의 원점이 되는데 이때의 x 좌표는 를 통해 input 해준다. 다른 는 의 결과값을 x 좌표로 가지게 되는데 이 에 input에 되는 x는 에서 나오는 값이고 y는 의 x방향 길이인 값이다. 이렇게 하면 두 이 에 따라 대칭(mirror)된 형태를 가지게 된다. 이 두 을 에 연결하여 section curve를 얻도록 하자.

이 section curve와 위에서 그린 curve가 교차하는 점을 찾기 위해서는 (Intersect > Physical > Curve | Curve)를 사용하면 된다. 이때 data matching의 방식은 ‘cross reference’로 해주면 된다. 이제 이 교차점을 이용하여 재배열한 curve들 위에 bridle joint를 그려보자

<CCX>를 보면 point 뿐만 아니라 tA와 tB가 있는 것을 알 수 있다. 이는 각 curve 위 교차 point의 parameter를 내보내는 것이다. 이것을 <evaluate curve>의 T에 연결하고 재배열 된 curve들을 C에 연결하면 해당하는 위치의 point를 재배열 된 curve 위에 찾아줄 수 있다. 즉 이 경우 point는 <orient>가 아닌 <evaluate curve>를 이용해서 찾아 준 것이다.

이제 이점으로부터 시작되는 line을 그려보자. 이 때 사용할 수 있는 것은 <line SDL>이다. 이는 S: Start point, D: Direction, L: Length를 input으로 가진다. <unit Y>를 방향에 연결하고 <offset>에 사용한 값을 <f2: x/2>를 이용하여 L에 연결하여주자.

이렇게 그려진 line에 <end point>를 이용하여 찾은 끝점을 찾아주자. 이것에 다시 <line SDL>을 연결하여 X 방향으로 line을 그려준다. 이 길이는 <sheet_thickness>가 된다.

이제 이 X방향으로 그려진 line의 끝점에서 처음 시작했던 curve로 돌아가보자. 먼저 <end point>를 이용하여 끝점을 찾아준다. 여기에 <line SDL>을 연결해주자. 이 때 line의 방향은 Y의 반대방향이므로 <unit Y>와 함께 음수를 L에 연결해주면 된다. 길이의 경우 정확한 길이를 알 수 없으므로 일단 충분히 긴 line을 그린 뒤 이것의 교차점을 찾아주자. 이번에는 line과 curve의 교차이므로 <CLX>(Intersect > Mathematical > Curve | Line)을 이용하면 된다. 이 point는 tree 구조를 가지고 있게 되는데 이를 <flatten>을 이용하여 data list로 바꿔주도록 하자.
위에서 X방향으로 그린 선의 end point와 방금 전에 찾은 교차point를 각 시작과 끝으로 하는 line을 그려주면 된다.

이제 <joint curves>(Curve > Util > Join curves)를 이용하여 각 line을 join 시켜주자.
위를 똑같이 다른 쪽의 점에도 적용시켜 준다.

Labeling

fabrication으로 넘어가기에 앞서 각 부재들에 labeling을 해보자. 잘라야 할 것이 수백 개에 이른다면 부재를 구분하기 위해서라도 꼭 labeling을 해주는 것이 좋다. 이때 label은 조립의 순서에 따르는 것이 좋다.
Label은 수와 text의 조합으로 이루어질 것이다. 즉 하나의 열에 여러 개의 부재들이 있다고 했을 때 left_wing_01 과 같은 방식으로 labeling을 할 수 있다.
이 예제에서는 일련의 수를 적용하여 각 부재의 위치를 표시해보도록 하자. <text tag>의 input으로는 label이 표시 될 frame과 표시할 text의 내용, 그리고 text의 크기가 있다.

각 방향의 부재의 수는 section curve를 <orient>하는데 사용했던 frame과 그 수가 일치한다. (위에서 선택된 component가 바로 우리가 <orient>에 연결하였던 frame의 list 이다.) 이 plane의 개수를 <list length>를 이용하여 찾은 뒤 그 수를 <series>의 C에 연결해준다.

여기서 나오는 수의 data list를 <text tag>의 T에 연결해주자. 이 때 <integer>는 수에 붙어있는 .0을 없애주는 역할을 한다. 즉 수가 12.0 인 경우 이것을 12로 바꿔주는 것이다.
부재의 list를 <text tag>의  L에 그대로 연결하면 label들이 각 부재의 꼭지점에 있는 frame의 중심에 표시되게 된다. 그러므로 이 전에 frame을 이동시키고 이것을 꼭지점에 있는 plane을 X 방향으로 1만큼, Y 방향으로 0.5 만큼 이동시켜보자. 이 경우 <sum> 을 이용하여 두 vector를 합한 뒤 <move>에 적용하였다. 이것을  <text tag>의 L에 연결시켜주면 된다.

이제 부재들이 그려지는 surface를 바꿔가며 부재들을 그려주면 된다. 이때 재료를 낭비하지 않도록 주의하자. 위 그림의 경우 sheet_3에서 부재의 일부가 sheet의 끝에 닿는다는 것을 알 수 있다. 이것을 조절해주기 위해 Grasshopper의 algorithm을 바꿀 수도 있다. 하지만 이것을 bake 한 뒤 Rhino에서 자르기 전에 이동시켜주는 것이 더 간단하다. 즉 어떻게 작업을 하는 것이 더 쉬울지를 잘 판단하는 것이 중요하다.

자르기(Cutting)

모든 준비가 끝났으면 이제 curve를 bake 한 뒤 부재를 자를 준비를 해보자. 아래에서 보이는 것 처럼 모든 부재를 재료의 사이즈와 양에 맞춰 잘 배열해보자. 이제 laser cutter를 사용할 준비가 모두 끝났다.

<a

조립(Assembly)

이 예제의 경우 부재의 조립은 어렵지 않다. 3d model과 비교해가며 조립하면 조립 순서와 부재의 위치를 쉽게 찾을 수 있을 것이다. 조립이 끝나면 종이를 이용하여 만든 surface가 완성될 것이다.

완성된 model

완성된 model

잘려진 부재, 조립할 준비가 되었다


 Fabrication을 잘 하기 위해서는 여러 가지 측면을 고려해야 한다. 어떠한 형상이어야 하는가, 어 떠한 재료를 사용해야 하는가, 어떤 제작도구를 이용하는가, 어떻게 조립할 것인가 등의 여러 사항에 따라 그 결과물이 달라질 수 있기 때문이다. 또한 project에 따라 fabrication에 필요한 data를 잘 추출해내는 것이 중요하다. 특히 결과물이 복잡한 기하체라면 조립의 규칙을 먼저 생각해보는 것 또한 무척 중요하다.

조립 방식; 흔한 재료와 간단한 joint로 제작하였지만 재료가 어떻게 만나는가와 점의 위치 data가 없다면 모형을 원하는 대로 제작할 수 없을 것이다.


 
 

이로서 Generative Algorithm의 연재를 마칩니다.
곧 pdf 합본으로 업로드할 예정입니다.
감사합니다.

 


 
[1] 이 전에 저자가 언급한 바는 없지만 위의 그림에서 보시다시피 top view에서 본surface의 왼쪽 아래 코너의 x, y좌표는 0이다. 만약 surface를 다른 곳에 그렸을 경우 이를 위의 그림에 맞게 옮기면 된다.
 

Generative Algorithm 039

8_2_Laser Cutting and Cutting based Manufacturing

 
복잡한 형태를 가진 3d model을 Laser cutter 가공이 가능하도록 만들어보자. Laser cutter를 이용하면 특히 가전면(developable surface)을 가진 모형이나 여러 면을 가진 접어서 만들어야 하는 모형(folded ones)을 제작할 때 매우 편리하다. Digital model에서 연결된 면들을 하나의 면이 되도록 편 뒤(unfold) 그 형태에 맞춰 모형재료를 자르고 다시 접거나 말아서 붙이는 방식으로 모형을 제작할 수 있기 때문이다. 즉 digital model의 면을 평평한 면의 단위로 분리하여 자른 뒤 이것을 다시 붙여가며 조립해가는 것이다. 복곡면(Double curved surface)의 경우도 위와 같은 방법으로 제작이 가능하다. 방울과 같은(blobby) 형태를 만들 경우에는 먼저 면을 두 방향으로 연속하는 section을 나눈 뒤 이 모양에 따라 재료를 자르고 다시 Bridle joint[1]등을 이용하여 격자형으로 조립할 수 있다.
즉 laser cutter란 판형재료를 가공할 수 있는 도구라는 것이다.  어떠한 형상이라도 연속하는 section과 같이 평평한 면으로 해석해내면 그 모형을 제작할 수 있다. 이때 재료는 종이, 금속, cardboard, 나무 등 무엇이든 가능하다.
이제부터 grasshopper를 이용하여 주어진 곡면을 sectioning을 이용하여 평평한 면으로 해석해보도록 하자.

Rhino에서 원하는 형상을 가진 surface를 그리자. 그리고 이 surface를 <geometry>를 이용하여 Grasshopper와 연동시킨다.
 

단면으로 해석하기(Ribs as Sections)

 
이 free-form surface의 모형을 제작하기 위해서는 먼저 면의 단면을 추출한 뒤 이것을 모형재료의 크기와 맞는 평평한 surface 위에 다시 그리도록 하자. 이때 Rhino에서 그려진 surface에는 두께가 없으므로 원하는 두께는 따로 설정해줘야 한다.

Sectioning을 하는데 사용되는 원리는 바로 면과 연속하는 평면을 교차시켰을 때 생기는 ‘curve를 사용하는 것이다. 먼저 <bounding box>를 이용하여 우리가 가공하고자 하는 3d model을 감싸는 최소한의 box를 구한다. 여기에 <box corners>(Surface > Analysis > Box corners)를 이용하여 이box의 각 꼭지점들을 추출하고 이중 두 끝을 잡아 각각 XZ plane과 YZ plane을 생성한다. 이제 이것을 가로와 세로 방향으로 이동시켜야 한다. 이를 위해 사용 되는 것이 <distance>와 <range> 이다. <distance>는 위에서 생성된 두 plane이 각각 y방향과 x 방향으로 이동하는데 사용되는 거리의 범위가 된다. 이것을 <range>를 이용하여 N만큼 나누어서 생기는 data list의 각 위치에 plane이 이동하게 된다.[2]

즉 주어진 면을 감싸고 있는 bounding box의 x와 y방향의 모서리의 길이와 꼭지점 하나를 추출한다. 이 꼭지점에 XZ plane을 생성하여 Y방향으로 연속 이동 시키고 YZ plane을 생성하여 X 방향으로 연속해서 이동시킨다. 이제 이 plane 들이 처음 연동시킨 surface와 교차되는 부분을 추출하면 우리가 원하는 section을 얻을 수 있다. 이 때 section의 개수는 <number slider>이용하여 N 값을 조절해주면 우리가 원하는 만큼 조절해줄 수 있다.

Plane의 원점(Origin)과 각 XY 방향은 위와 같이 frame으로 표시되게 된다. 위 그림에서 볼 수 있는 것처럼 각 frame들은 모서리에 수직방향으로 생기게 된다.

이제 이 plane들과 surface가 교차(intersect)하는 부분을 찾아보도록 하자. 이 경우 surface(Brep)과 plane이 교차하는 것이므로 intersect component 중 <Brep | Plane intersect>(Intersect > Mathematical > BRep | Plane) 를 사용하면 된다. 즉 두 개의 <Brep | Plane Intersect>를 만든 뒤 이 둘의 Brep에 처음 surface를 연동시킨 <geometry>를 연결시켜 준다. 또한 이 전 단계에서 얻어진 X방향으로 연속된 plane과 Y방향으로 연속된 plane들을 P에 연결시켜주면 된다.

이것의 결과물은 위에서 보는 것과 같이 각각 X, Y 방향으로 연속되는 curve이다.

Section 배열하기 (Nesting)

다음 단계는 바로 위에서 얻어진 curve들을 평평한 평면 위에 배열하는 것이다. 이것은 이 후 laser cutter를 이용하여 재료를 자르는데 사용될 것이다. 아래 그림과 같이 재료와 같은 크기를 가지는 직사각형의 Surface 을 그린다. 그리고 이 surface를 아래와 같이 연속하여 배열시킨다.

이제 <Orient>(XForm > Euclidian > Orient)를 이용하여 위에서 얻은 curve를 위 surface 위에 그려보자. <Orient>는 먼저 방향을 바꿀 G: geometry와 이동의 기준으로 사용 될 A: reference plane, 그리고 이 geometry가 이동되어 그려질 대상이 되는 B: target plane으로 이루어진다. 먼저 <Orient>에 G는 위에서 <Brep | Plane Intersect>에서 나오는 Curve가 될 것이고 A: reference plane은 위에서 section curve를 얻기 위해서 사용했던 plane들을 사용할 수 있다. 이제 target plane을 만들어보자.

먼저 위에서 그린 직사각형의 surface를 <surface>를 이용하여 Grasshopper와 연결시킨다. 이것에 <Surface Frame>(Surface > Util > Surface Frames)을 연결하도록 하자. 이것은 면 위에 UV 방향으로 우리가 원하는 수 만큼의 frame (plane의 원점과 방향이 표시된)을 생성할 수 있다.

<surface frame>에 생기는 frame의 개수는 U,V에 입력되는 수를 통하여 조절할 수 있다. 이 때 주의해야 할 것은 U에 1을 입력하더라도 이 방향으로 생성되는 frame은 총 2열이라는 것을 알 수 있다. Surface를 U 방향으로 1로 나누는 것이기 때문에 시작인 0과 끝이 1에 각각 frame이 생성되기 때문이다.[3] 즉 우리가 필요한 것 보다 더 많은 수의 frame이 생기게 된다. 이를 위해서 우리가 필요한 수만큼의 plane을 골라내어야 한다. 이 때 사용 가능한 것이 <split>이다. 이것은 L을 통하여 data list가 들어올 때 i: integer에 입력되는 수 만큼의 data 를 A로, 그 나머지를 B로 내보내주는 역할을 한다. 먼저 <Brep | Plane Intersection>에서 나오는 C의 개수를 <list length>를 이용하여 찾아준다. 이것을 split의 i에 연결시키면 우리가 원하는 수 만큼의 plane을 취할 수 있다. 또한 section이 surface의 모서리와 닿는 것을 방지하기 위하여 X방향으로 1만큼 이동시켜 주었다.

위의 algorithm의 결과물로 위처럼 curve들이 cutting sheet에 그려졌다.
 
 
 


 
[1] http://en.wikipedia.org/wiki/Bridle_joint
[2] 예를 들어 X방향으로의 길이가 50이라고 했을 때 이 길이를 <range>의 D에 넣고 N에 4를 넣으면 (0.0, 12.5, 25.0, 37.5, 50.0) 이라는 data list가 생긴다. 이는 현재 0.0에 위치하는 YZ plane이 12.5, 25.0, 37.5, 50.0 에도 생기게 되는 것을 의미한다.
[3] 이 때 주의할 점은 0.8.0004build에서는 <surface frame>에서 나오는 frame이 tree data의 형태로 나온다는 것이다. 즉 <surface frame>과 <split>사이에 <flatten tree>를 사용하면 위와 같은 결과를 얻을 수 있다.