중요했던 부분:
- point(): Point Function
point()은 윗 geometry나 attribute관련 노드들이 attribute wrangle노드로 연결 되었을때 각각의 포인트 넘버에 대한 attribute 정보들을 불러오는 function이다.
point (노드가 들어간 input의 순서, 불러오려는 attribute, 포인트 넘버의 대한 정보)
geometry가 wrangle 노드에 연결되었을 때의 예시:
eg) 보통 attribute에 값들을 지정해주기 위해 썼던 코드 방식은:
vector color; // vector color라는 변수가 있는데
color = {1, 0, 1}; // color는 (1, 0, 1)으로 지정되어있다.
@Cd = color; // @Cd 색깔값에 color라는 변수를 넣겠다.
eg) point()을 활용하여 이렇게 작성 할 수 있다.
만약 노드를 이렇게 이어붙였을때:

vector color = point (1, "P", 3); // 위의 예시를 예로 들자면 1번 인풋으로 들어간 지오메트리 즉 box의 3번 포인트 넘버의 attribute정보 즉 x/y/z 포지션을 불러다가 vector variable color으로 저장해주는 사실을 알 수 있다. 즉 만약 box의 3번 포인트 정보의 @P 정보가 (1, 1, 0) 이라면,
v@color = color; // 유저가 직접 만든 vector attribute color를 생생해 줌으로써 geometry spreadsheet상에 color[0], color[1], color[2]에 각각 1, 1, 0씩 뜰 것이다.
eg) int select = chi ("SELECT"); // select라는 변수를 만들어 주었는데 이 select라는 변수는 chi()을 이용함으로써 파라미터에서 정보를 불러오고있다.
vector color = point (1, "P", select); // 1번 인풋으로 연결된 geometry의 파리미터로 지정된 포인트 넘버의 포인트의 위치값을 color라는 vector variable에 저장할 것이다.
@Cd = color; // 방금 우리가 만들어둔 vector variable color가 @Cd값 즉 색깔값으로 들어온것을 확인 가능함. 파라미터상에서 SELECT값을 바꿔줄수록 지정된 1번 인풋 geometry의 포인트 넘버가 바뀌어 각각의 포인트들의 위치값도 바뀔것이므로 grid의 전체적인 색도 바뀌어 갈것이다.

geometry가 wrangle 노드에 연결되었을 때의 예시:

정보를 원초적으로 생성한 wrangle노드의 vex (윗 노드):
eg) s@input = "TWA"; // string attribute input에 "TWA"라는 글씨를 저장
정보를 받아오려는 wrangle노드의 vex (아랫 노드):
eg) s@myInput = point (1, "info", 0); // 모든 포인트에 대하여 아래 새롭게 정의된 string attribute myInput에 1번 노드인풋으로 들어온 @input의 0번 포인트 값을 저장.

*내가 확인한 사실:
point()으로 윗 1번 2번 3번 인풋에 연결된 attribute 정보를 받아오려는 wrangle 노드에는 반드시 0번 인풋이 꽂혀져 있는 상태여야한다 0번 input을 비운채 1번 2번 3번 인풋에 꽂혀진 attribute 특정정보를 가져오려면 geometry spreadsheet상에 아무것도 뜨지 않는다. 이는 왜냐하면 attribute wrangle은 0번 인풋에 꽂혀진 정보만을 우선시 여기며 1번 2번 3번 인풋에 꽂혀진 정보들은 point()으로 불러와진 attribute정보들은 0번 인풋의 존재 없이 geometry spreadsheet에서 읽을 수 없기 때문이다.
- Visualisation -> Visualisers -> Scene -> Marker
각기 해당하는 point number의 특정 attribute값들을 scene view에 디스플레이 해주는 툴

- Attribute Randomise
Attribute 노드 중 하나로써 특정 attribute를 유저가 직접 선택하게 하거나 만들게 만들어 그 attribute에다 각기 랜덤한 값들을 부여한다.

eg) attribute randomise가 적용되어있는 상태에서...
정보를 원초적으로 생성한 wrangle노드의 vex (윗 노드):
@num = @num*100; // 방금 attribute randomise에서 생성한 @num에 100을 곱해줌. Attribtue Randomise 노드에서 0과 1사이의 수치로 저장되게끔 설정되었기 때문에 100을 더해주어 큰 값으로 만들어줌.
@num = floor (@num); // floor()을 사용하여 내림해줌으로써 소수점 아래에 있는 수를 깔끔하게 없애줌
정보를 받아오려는 wrangle노드의 vex (아랫 노드):
int mypt = @ptnum; // 각각의 @ptnum 포인트 넘버들을 int variable mypt에 저장
i@mypt = mypt; // integer variable mypt를 geometry spreadsheet에 디스플레이하고 integer attribute mypt으로 저장
float getInfo = point (1, "num", mypt); // 1번 input에 꽂힌 노드의 mypt (각기 포인트들의 @ptnum을 상징하는 위에서 선언한 변수)에 해당하는 포인트들의 attribute num의 값들을 float varaible getInfo 에 할당함.
f@num = getInfo; // 방금 선언된 variable getInfo를 float attribute num으로 저장해줌으로써 geometry spreadsheet상에서 각기 다른 point number들의 각기 다른 attribute 값들을 디스플레이 하게함. 이 값들은 Visualisations을 사용하여 Scene View에서 더욱 손 쉽게 어떤 point number에 어떤 Attribute가 할당되어 있는지 확인 가능케 할 수 있음.

- Point Jitter
포인트들을 널리 흩뜨리게 하는 노드
- 상기시키면 좋을 것.
eg) @P = @P + {1, 0, 0}; // 모든 포인트에 대하여 @P 포인트 위치값에 {1, 0, 0}을 전부 더하여라
eg) i@id = @ptnum; // geometry spreadsheet에서 @ptnum을 유저가 생성한 attribute @d으로써 값들을 보이게함
// @ptnum, @numpt, @Time과 같은 built-in attribute들은 geometry spreadsheet 상에서 바로 드러나진 않지만 선언만 해주면 바로 뜨는 Type Casting이 따로 필요없는 Attribute이다. 위의 예시와 같이 ptnum을 유저가 선언한 i@id에 저장하여 spreadsheet상에서 @ptnum값들을 @id하에 뜨게 한다.
| id | ptnum (표시되지 않음) | |
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
- minpos(): Minpos Function
minpos()는 Vector 값을 내보내는 function이다. 어떤 점에서 geometry를 주변에 두었을때 제일 가까운 geometry의 한 점의 Attribute를 불러오는 역할을 한다. 모든 포인트들에 대하여 특정 포인트에서 geometry까지의 가장 가까운 attribute값을 vector 값으로 불러와라고 하는 function.
eg) minpos (1, @P); // 0번 인풋으로 연결된 geometry의 모든 점들에서로부터 1번 인풋에 연결된 geometry의 제일 가까운 point의 @P (position 위치값)을 불러와달라.
- 방금 윗코드를 적용했을때 이런 방식으로 나타날 것이다라고 표현하는 테이블
| P[x] | P[y] | P[z] | |
| 0 | 2 | 3 | 7 |
| 1 | 4 | 3 | 6 |
| 2 | -5 | 3 | 8 |
| 3 | -6 | -7 | -5 |
| 4 | 2 | 0 | -5 |
// 0번 point에서로부터 1번노드에 연결된 geometry를 구성하는 점들중 가장 가까운 점의 위치값(@P)은 (2, 3, 7)이다.
// 1번 point에서로부터 1번노드에 연결된 geometry를 구성하는 점들중 가장 가까운 점의 위치값(@P)은 (4, 3, 6)이다.
// 2번 point에서로부터 1번노드에 연결된 geometry를 구성하는 점들중 가장 가까운 점의 위치값(@P)은 (-5, 3, 8)이다.
// 3번 point에서로부터 1번노드에 연결된 geometry를 구성하는 점들중 가장 가까운 점의 위치값(@P)은 (-6, -7, -5)이다.
// 4번 point에서로부터 1번노드에 연결된 geometry를 구성하는 점들중 가장 가까운 점의 위치값(@P)은 (-2, 0, -5)이다.

eg) vector pos = minpos (1, @P); // 1번 input으로 들어간 geometry를 구성하는 포인트들 중 가장 가까운 포인트의 위치값을 제발 좀 알려주세요.
v@newPos = pos; // vector variable pos값들을 vector attribute newPos에 저장하여 geometry spreadsheet에 디스플레이함.
float d = distance (@P, pos); // 0번 인풋으로 들어간 geometry의 모든 point들의 위치로부터 1번 input으로 들어간 geometry를 구성하는 point들중 가장 가까운 점의 위치 사이의 거리들을 수치로 출력하여 float variable d에 저장함.
d *= chf ("SCALE"); // 위에 선언한 d값을 chf()으로 조정가능케함. sin()을 적용시에 더욱 촘촘해지는 파장을 형성 가능케함.
@Cd = 0; // 모든 Color값을 0으로 초기화 해주세요
@Cd.r = d; // 만약 d값을 곧바로 @Cd.r에 저장해준다면 어떻게 될지 궁금해서 해보았다. 예를 들은 grid를 구성하는 포인트들중 rubbertoy를 구성하는 포인트들의 위치로부터 제일 멀리 떨어져 있을때 d값은 더욱 커져 색이 진해져 가는것을 확인 할 수 있었다. 또한 SCALE 파라미터를 늘릴수록 0을 제외한 나머지 값들은 파라미터에 입력된 값들이 곱해지기 시작하여 rubbertoy이가 있는 자리를 제외한체 더욱 선명하게 빨간색을 띄는 것을 확인 할 수 있었다.

or @Cd.r = sin(d); // sin()을 d에 적용한다면 어떻게 될까? 지금까지 배워왔던 것처럼 d값에 파장의 형태를 띈 색깔 파형이 적용되어 rubbertoy를 중심으로한 rubbertoy모양의 파형을 띄는것을 확인 할 수 있었다. Sine Wave가 적용된 grid의 모든 점들의 위치에서부터 rubbertoy를 구성하는 포인트들중 가장 가까운 포인트의 위치 사이의 거리 길이를 빨간색으로 나타내어라.

eg)
우선 scatter을 이용해 rubbertoy의 두 점들만있게끔 만들어주고 그 점들을 기준으로 platonic의 가장 가까운 점들을 생성하기로 했다.
첫번째 Wrangle 노드:
vector pos = minpos (1, @P); // 0번 인풋으로 들어온 geometry (Rubbertoy)의 모든 점들로부터 1번 인풋으로 들어온 geometry (Platonic)를 구성하는 포인트들중 가장 가까운 점의 위치값을 vector variable pos에 집어넣어라
v@newPos = pos; // 위에 선언된 vector위치값들을 vector attribute newPos에 저장하여 geometry spreadsheet에 0번 geometry (Rubbertoy)를 구성하는 점들마다 해당하는 vector값들이 뜨게끔 한다.
두번째 Wrangle 노드 (for Platonic, platonic을 구성하는 점들중 가장 가까웠던 점들을 point로 생성시키기 위해) :
vector a = point (1, "newPos", 0); // 1번 인풋으로 들어온 geometry혹은 Attribute값 (Platonic)의 0번 포인트의 newPos값을 불러와 vector varaible a에 저장하여라.
vector b = point (1, "newPos", 1); // 1번 인풋으로 들어온 geometry혹은 Attribute값 (Platonic)의 1번 포인트의 newPos값을 불러와 vector varaible b에 저장하여라.
addpoint (0, a); // variable a가 적고있는 수치에 기반하여 point를 생성
addpoint (0, b); // variable b가 적고있는 수치에 기반하여 point를 생성
세번째 Wrangle 노드 (for Rubbertoy):
// 이는 나중에 add노드를 이용하여 동일한 값을 지는 attribute를 가진 point들끼리 선으로 연결해줄때 Attribute Name에 Visualisation을 설정할때처럼 이름을 입력해주어야 Add노드가 어떤 Attribute를 선으로 이어야 할지 알수 있는데, @ptnum을 유저생성 Attribute @id로 저장한다면 나중에 id를 입력해줌으로써 동일한 Attribute끼리 선으로 이어 질 수있다.
i@id = @ptnum; // geometry를 구성하는 모든 point들 즉 이번상황에선 rubbertoy를 구성하는 모든 point number들을 유저가 생성한 i@id로써 저장한다.
세번째 Wrangle 노드 (for Platonic):
i@id = @ptnum; // geometry를 구성하는 모든 point들 즉 이번상황에선 Platonic을 구성하는 모든 point number들을 i@id로써 저장한다.
그 후:
Wrangle노드들로 생성된 점들을 merge로 다 보이게하고 add로 선으로 이어주면 rubbertoy의 두점으로부터 가장 가까운 platonic의 점들이 어디있는지 확인 할수 있다. 만약 Platonic을 움직이게 만들어 가장 가까운 점들의 위치에 변화를 준다면 유동적으로 minpos()에 해당하는 점들이 유동적으로 바뀌는것을 확인 할 수 있었다.
*minpos()는 vector값들을 불러옴으로써 점선면 상관없이 모든 vector값들을 할당하는 것을 알 수 있었다.
eg) // 앞서 만든 rubbertoy 모양을 본뜬 grid의 파형을 적용하여 요런 모션도 만들 수 있었다.
vector pos = minpos (1, @P); // 0번인풋으로 들어온 geometry의 모든 점들로부터 1번인풋으로 들어온 geometry의 가장 가까운 포인트들의 위치값들을 vector variable pos에 저장하여라.
float d = distance (@P, pos); // 0번 인풋으로 들어온 geometry의 모든 포인트와 1번 인풋으로 들어온 geometry의 가장 가까운 포인트들 사이의 거리길이를 float variable d로 저장하여라.
d *= chf ("SCALE"); // 거리길이값을 SCALE로 조정 가능케함
@Cd = 0; // geometry의 컬러값을 0으로 초기화
@Cd.r = sin (d); // sine wave가 적용된 d값을 빨간색으로 나타나게 하라
* merge노드나 copytopoint노드를 활용하여 여러개의 모양의 geometry가 grid상에서 한번에 보여지는 것도 가능하다.
- nearpoint(): Nearpoint Function
nearpoint()는 Integer 값을 내보내는 function이다. 어떤 점에서 geometry를 주변에 두었을때 제일 가까운 geometry의 한 점의 point number를 불러오는 역할을 한다. 모든 포인트들에 대하여 특정 포인트에서 geometry까지의 가장 가까운 @ptnum값을 integer 값으로 불러와라고 하는 function.
eg) nearpoint (1, @P); // 0번 인풋으로 연결된 geometry의 모든 점들에서로부터 1번 인풋에 연결된 geometry의 제일 가까운 포인트의 @ptnum값을 불러와달라.
eg) int getptnum = nearpoint (1, @P); // 0번 인풋으로 연결된 geometry의 모든 점들에서로부터 1번 인풋에 연결된 geometry의 제일 가까운 포인트의 @ptnum값을 불러와달라. 그리고 그 값들을 Integer variable getptnum에 저장하라
i@id = getptnum; // 방금 선언한 integer variable getptnum을 input attribute id로 저장하여 geometry spreadsheet상으로 보여주어라.
eg) int close = nearpoint (1, @P); // 0번인풋으로 들어온 geometry의 모든 포인트들로부터 1번인풋으로 들어온 geometry를 구성하는 점들중 가장 가까운 포인트의 포인트넘버들을 integer variable close에다 저장하세요. 만약 여기서 1번인풋으로 들어온 geometry가 7개의 포인트들만 가지고 있다고 가정하면 0번인풋으로 들어온 geometry를 구성하는 모든 point들은 가장 1번 인풋 geometry의 가장 가까운 각기 다른 포인트들을 찾아 그 포인트들의 포인트 넘버들을 close변수로서 저장한다.
@Cd = point (1, "Cd', close); // 1번 인풋으로 들어온 geometry나 attribute노드에서 close(여기서 close는 nearpoint()으로 반환된 각기 다른 포인트 넘버들)에 해당되는 값을 가진 포인트 넘버들의 @Cd (색깔 값들)을 불러와 @Cd에 저장하여 색깔로써 보여주어라.
여기서 0번 인풋으로 들어온 geometry의 모든 포인트들은 close 변수상에서 close라는 integer variable을 통해 한 부분이 일정한 @ptnum으로 통일 되었음. 이 @ptnum값에 해당하는 1번인풋으로 들어온 geometry의 @Cd값들을 0번 인풋으로 들어온 geometry의 @Cd값 즉 색깔값으로 지정해준다면 부분 부분 7개의 포인트들의 위치를 중심으로 그 주위 통일된 색깔을 가진것을 확인 할 수있음.
풀어쓴다면:
vector getColor = point (1, "Cd", close); // point()을 이용해 1번 인풋으로 들어온 geometry나 attribute의 close에 해당하는 point number를 가진 @Cd값들을 가져와 0번 인풋으로 들어온 geometry안에 vector variable getColor에 저장하여라
@Cd = getColor; // 그리고 방금전 선언된 getColor variable을 @Cd로 적용하여 0번 인풋으로 들어온 geometry의 색깔 값으로 저장하여 보여주어라.
vector newPos = point (1, "P", close); // point()을 이용해 1번 인풋으로 들어온 geometry나 attribute의 close에 해당하는 point number를 가진 @P값 (포인트 위치)들을 가져와 0번 인풋으로 들어온 geometry안에 vector variable newPos에 저장하여라. 아까하고 식은 똑같지만 여기선 1번 인풋으로 들어온 geometry값의 @Cd값이 아닌 @P값임.
float d = distance (@P, newPos); // 0번 인풋으로 들어온 geometry의 포인트들로부터 각기 그 포인트들에게 각기 할당된 1번 인풋으로 들어온 geometry를 구성하는 포인트들의 위치 까지의 거리길이를 float variable d에 저장하여라.
@P.y = -d; // 그리고 선언한 float variable d를 @P.y 즉 높이값으로 주어 newPos값들을 중심으로 한채 멀어질수록 점점 d값은 커지므로 점점 높어지는 모양을 형성함. 다만 d에 마이너스가 곱해졌으므로 그반대인 d값이 점점 더 낮아지는 @P.y와 d가 반비례적인 모양을 형성함.
- 이와같이 맞추게 되면 grid와 grid를 이용한 7개의 포인트들을 사용해서 위 vex를 적용하였을때 그리드의 모든 점에대한 포인트와 윗 노드에서 불러온 포인트들의 위치사이의 거리길이를 높이값으로 표현하여 깔대기모양이 여러개가 있는 모양이 나타나야한다. 앞서 말했듯 d값에 마이너스가 곱해졌기 때문에 뒤집혀진 여러 깔대기 모양을 형성하고 위에서 불러온 각기 newPos에서부터 가장 멀리 떨어진 grid point들 즉 어느 newPos포인트들에서도 가장 멀리 떨어진 grid들의 point들은 식을 정용하엿을때 높이상에서 가장 낮은 값을 가져 계곡 골짜기 같은 형태를 띄게 된다.

Exercises:
1. Pull the following wrangle apart, set the chramp to mostly flat, with a thin triangle in the middle, lots of divisions on the grid:
나는 cgwiki님이 이미 만들어주신 코드에 해석을 해보기로 하고 그다음 직접 써나가고 Joy of Vex에 있는 예시와 똑같이 만들어 주기위해 알맞은 노드들을 배합하여 비슷한 결과를 만들었다.
/* 0번 인풋으로 연결된
geometry의 모든 점들에서로부터 1번 인풋에 연결된
geometry의 제일 가까운 포인트의 @ptnum값을 불러와달라. */
int pt = nearpoint(1,@P);
/* point()을 이용해 1번 인풋으로 들어온 geometry나
attribute의 pt 해당하는 point number를 가진
@P값들을 가져와 0번 인풋으로 들어온 geometry안에
vector variable pos에 저장하여라*/
vector pos = point(1,'P',pt);
/* 0번 인풋으로 들어온 geometry의 포인트들로부터
각기 그 포인트들에게 각기 할당된
1번 인풋으로 들어온 geometry를 구성하는 포인트들의
위치 까지의 거리길이를 float variable d에 저장하여라.*/
float d = distance(@P, pos);
// d값 거리길이값을 ch()을 적용함으로써 scale parameter로 조정 가능케함
d *= ch('scale');
// d에 랜덤한 값을 추가하여 크기가 각기 다 일정하지 않게 함
d += rand(pt);
// d에 @Time을 빼주어 가장자리로 흩어나가는 모션을 적용함
d -= @Time;
/* @P.y값 높이값에 chramp()을 적용하여 파형의 쉐입을 적용할 수 잇게하고
또다른 ch()을 곱하여 높이설정을 할 수 있게함*/
@P.y = chramp('pulse',d)*ch('amp');
이해가 안되었던 부분:
- minpos()에서의 두번째 인풋은 반환 하려는 정보의 attribute으로 알고 있다. 비슷하게 nearpoint()에서 nearpoint()는 배운바로는 minpos()와 다르게 integer value인 @ptnum값만 반환하는 것으로 알고 있는데 굳이 두번째 인풋에 @P를 써야 하는지 의문이 생겼다. 그리고 만약 @ptnum을 반환한다면 @ptnum을 써야하는것이 아닌가라는 의문이 들기도 하였다. 혹시 nearpoint()에서 반환하려는 integer값이 point number뿐만이 아닌 또 다른 값이 있나? nearpoint()에 있는 두번째 인풋의 정확한 뜻을 내가 잘못 알고 있나?라는 아리송한 생각이 들곤 하였다. cgwiki님의 사이트와 twa선생님의 강의에서는 두번째 인풋안에 @P만 쓴 경우를 보여주어 minpos()상에서는 반환하려는 vector attribute가 많다 그렇지만 nearpoint()에는 과연 @ptnum이나 @numpt말고의 다른 integer attribute들이 뭐가 있을지 궁금케했다. 그것도 그렇지만 우선적으로 그렇다면 nearpoint()의 두번째 인풋에 @P를 굳이 써야 하나라는 생각이 들었다. @P는 벡터값인데 왜 nearpoint()에도 두번째 인풋에 @P을 넣을까 라는 궁금증이 들었다.
- 항상 그렇지만 이번 강의와 공부는 복습과 복습을 반복하면서 코드 한줄 한줄 곱씹으면서 작업했던 것같다.
공부하면서 들었던 생각:
와... 지난번에 두 번 분명 들었는데.. 그때는 이해를 완전히 못하고 그냥 넘겨짚어갔는지 이번에 완전 깊게 공부하고 나니 새로운 내용을 배운것처럼 머리가 폭발하기 시작하였다... 자신만만했던 나를 반성한다. 7일차오니 내가 똑똑한 편이 아니었구나를 새삼 실감하게된다. 그러고 나니 오히려 더욱 모티베이션이 생겨서 더 열심히 해야겠다는 생각이 든다. 아마 다이어리를 쓰면서 제일 시간도 오래걸렸던것 같다. 보통 다이어리를 작성할때는 시간을 최대한 많이 쓰지 말자라는 생각으로 임하게 되는데 이번 강의에 관한것은 코드를 하나하나 곱씹고 또 반복하고 또 곱씹어야 완전히 내것이 되겠다는 것을 지난 두 번보고 잊어버렸다는 사실때문에 더욱 실천하고 시간도 오래 걸렸던 것 같다. 이번 강의는 어렵기도 했지만 무엇보다도 배우는 양이 다른 강의 때에 비해 현저하게 어마무시하게 많았고 attribute wrangle의 인풋을 여러개 사용하니까 햇갈리는 부분이 컸다. 또한 사용을 안해봤던 노드들의 양이 현저히 많아져 머리가 터지는데 일조한것같다. 또한 중간에 rubbertoy와 platonic을 이용한 부분은 지난 최초입문강의 의자만들기 때처럼 노드의 양이 많아져 가뜩이나 vex로 작업하는데 진짜 와 이거 나중에 어케하냐라는 생각이 들기도 했다. 아마 지금 내가배우는것은 vex의 완전 기초중의 기초이지만 벌써 어렵다는 것을 느끼고보니 새삼 후디니가 만만치 않다는것을 완전하게 깨닫는 day였기도 했던 것 같다. 내일 중간고사 그리고 주말에 완성할 과제그리고 day 8공부 등 이번주 주말은 정말 바쁘게 보내야 할것 같다. 아마 이렇게 바쁘게라도 해야 후디니 발끝이라도 잡을것같다. 그렇지만 항상 모든것에는 기초가 중요하듯이 나도 기초하나는 완전히 마스터를 해야 나중에 Destruction이든 Particle이든 뭐든 하고싶은것을 해야한다는 생각이 든다. Joy of Vex가 그 기초를 다질 수 있다는 초석이 된다는 사실을 상기시키고 마음을 단단히 먹어야 겠다는 생각이 든다.