방향 선호 셸 추출
이런저런잡다구리/Research2004. 6. 8. 작업노트로 부터 정리 해 둠.
오브젝트가 향하는 방향값은 다음과 같이 정의되어있다.
4 | 0 | 5 |
3 | C | 1 |
7 | 2 | 6 |
첫번째 테이블, 즉 거리가 1일 때의 갯수는 8개이며 거리에 비례해 8의 배수로 늘어난다.
1st Table
0, 4, 5, 3, 1, 7, 6, 2
1, 5, 6, 0, 2, 4, 7, 3
2, 6, 7, 1, 3, 5, 4, 0
3, 7, 4, 2, 0, 6, 5, 1
4, 3, 0, 7, 5, 2, 1, 6
5, 0, 1, 4, 6, 3, 2, 7
6, 1, 2, 5, 7, 0, 3, 4
7, 2, 3, 6, 4, 1, 0, 5
2nd Table
0-0, 4-0, 5-0, 4-4, 5-5, 4-3, 5-1, 3-3, 1-1, 7-3, 6-1, 7-7, 6-6, 7-2, 6-2, 2-2
0-0의 의미는 0번 방향에서 다시 0번방향이라는 의미...
이 관계를 테이블로 정리 해 보면 다음과 같다.
4,4,4,4 | 4,4,4,0 | 4,4,0,0 | 4,0,0,0 | 0,0,0,0 | 5,0,0,0 | 5,5,0,0 | 5,5,5,0 | 5,5,5,5 | ||
(-4,-4) | (-3,-4) | (-2,-4) | (-1,-4) | (0,-4) | (1,-4) | (2,-4) | (3,-4) | (4,-4) | ||
4,4,4,3 | 4,4,4 | 4,4,0 | 4,0,0 | 0,0,0 | 5,0,0 | 5,5,0 | 5,5,5 | 5,5,5,1 | ||
(-4,-3) | (-3,-3) | (-2,-3) | (-1,-3) | (0,-3) | (1,-3) | (2,-3) | (3,-3) | (4,-3) | ||
4,4,3,3 | 4,4,3 | 4,4 | 4,0 | 0,0 | 5,0 | 5,5 | 5,5,1 | 5,5,1,1 | ||
(-4,-2) | (-3,-2) | (-2,-2) | (-1,-2) | (0,-2) | (1,-2) | (2,-2) | (3,-2) | (4,-2) | ||
4,3,3,3 | 4,3,3 | 4,3 | 4 | 0 | 5 | 5,1 | 5,1,1 | 5,1,1,1 | ||
(-4,-1) | (-3,-1) | (-2,-1) | (-1,-1) | (0,-1) | (1,-1) | (2,-1) | (3,-1) | (4,-1) | ||
3,3,3,3 | 3,3,3 | 3,3 | 3 | C | 1 | 1,1 | 1,1,1 | 1,1,1,1 | ||
(-4,0) | (-3,0) | (-2,0) | (-1,0) | (0,0) | (1,0) | (2,0) | (3,0) | (4,0) | ||
7,3,3,3 | 7,3,3 | 7,3 | 7 | 2 | 6 | 6,1 | 6,1,1 | 6,1,1,1 | ||
(-4,1) | (-3,1) | (-2,1) | (-1,1) | (0,1) | (1,1) | (2,1) | (3,1) | (4,1) | ||
7,7,3,3 | 7,7,3 | 7,7 | 7,2 | 2,2 | 6,2 | 6,6 | 6,6,1 | 6,6,1,1 | ||
(-4,2) | (-3,2) | (-2,2) | (-1,2) | (0,2) | (1,2) | (2,2) | (3,2) | (4,2) | ||
7,7,7,3 | 7,7,7 | 7,7,2 | 7,2,2 | 2,2,2 | 6,2,2 | 6,6,2 | 6,6,6 | 6,6,6,1 | ||
(-4,3) | (-3,3) | (-2,3) | (-1,3) | (0,3) | (1,3) | (2,3) | (3,3) | (4,3) | ||
7,7,7,7 | 7,7,7,2 | 7,7,2,2 | 7,2,2,2 | 2,2,2,2 | 6,2,2,2 | 6,6,2,2 | 6,6,6,2 | 6,6,6,6 | ||
(-4,4) | (-3,4) | (-2,4) | (-1,4) | (0,4) | (1,4) | (2,4) | (3,4) | (4,4) | ||
정리결과 재미난 규칙을 발견함.. 기준좌표를 중심으로 6-2-2-2 위치의 좌표는 6방향 옵셋값인 (1,1)과 2방향 옵셋값인 (0,1)을 그 반복횟수만큼 옵셋시킨 값이 된다. (1,1) + (0,1) + (0,1) + (0,1) = (1,4).
각 방향의 '어깨걸이' 방향을 좌우 순서로 정리하면 다음과 같다.
0 - 4, 5
1 - 5, 6
2 - 6, 7
3 - 7, 4
4 - 3, 0
5 - 0, 1
6 - 1, 2
7 - 2, 3
단계 1의 방향을 추출해 보자.
1의 왼쪽 오른쪽인 5, 6까지 추출... 5번의 왼쪽 0, 6번의 오른쪽 2,
다시 0번의 왼쪽 4, 2번의 오른쪽 7. 마지막으로 4의 왼쪽 3 또는 7의 오른쪽 3.
1, 5, 6, 0, 2, 4, 7, 3
어깨걸이 좌표 테이블로부터 추출이 가능하다는 얘기가 됨.
기준좌표로부터 거리 3인 위치를 6번방향 기준으로 추출할 경우...
먼저 3개의 인자를 갖는 바이트배열 두 개를 준비한다. 각각 오른쪽, 왼쪽값이 된다.
DirArr_R, DirArr_L : TByteArray;
초기값은 두 방향 모두 6-6-6 으로 채운다. DirArr_R[0], [1], [2] := 6;
이 인자들의 값을 해당 루프만큼 바꿔가며 방향을 추출할 수 있다.
총 루프 횟수는 거리값인 3 * 8 / 2 -1 = 11 번이 된다.
(하나의 방향이 모두 치환되는 횟수는 거리값, 즉 이경우 3번이 된다.)
시작방향이 0~3이면 앞부분을 치환, 4~7이면 뒷부분을 치환한다.
RepPos: Integer;
오른쪽을 기준으로 설명 해 보자. 시작방향, 즉 DirArr_R[0] 값이 6이므로 뒷부분 치환.
RefPos:= 0;
RepPos:= 거리 -1;
IncVal := -1; // RepPos를 줄이는 참조값.
또한 6의 오른쪽 방향은 ND2CD_TBL[6][7] => 2 이므로 루프 첫번째 값은 [6-6-2] 이다.
DirArr_R[RepPos] := ND2CD_TBL[ DirArr_R[RefPos] ][7];
RepPos는 하나 줄인다.
Inc(RepPos, IncVal);
RepPos가 0보다 작아지면 RepPos를 0으로, RefPos를 거리-1로, IncVal을 1로 수정.
RepPos가 거리보다 크거나 같아지면 RepPos를 거리-1로 RefPos를 0으로, IncVal을 -1로 수정.
이 과정을 총 루프횟수만큼 반복한 후 마지막 방향은 처음방향의 역방향으로 결정.
또는 왼쪽, 오른쪽 아무쪽이나 이 과정을 한 번 더 진행시켜 결정.
얻어낸 좌표옵셋의 거리제곱이 주어진 (거리+1)의 제곱보다 작은 경우만 범위로 인정.
이렇게 추출한 점열들은 결국 원형이 된다. 이 때 원형 내부에 꽉 차는 축직교 정사각형의 범위는 굳이 거리를 재지 않아도 원 내부이며 따라서 단순 비교문만으로 처리할 수 있다. 주어진 거리에 cos(45) 값을 곱한 후 반올림하면 사각영역의 경계값을 얻게 되며 이 경계안에 포함되는 영역은 거리비교를 하지 않도록 하자.
이 경계값은 스텝에 바로 대응된다. n번째 스탭에서 (n <= 경계값)의 조건을 만족 한다면 거리값을 잴 필요없이 원형 범위 이내가 된다는 이야기..
추출좌표의 총 갯수는 ((추출하려는 거리 * 2) -1)^2 -1 이 된다. 여기서 -1은 원점을 뺐기 때문이다.
지금까지의 정리를 코딩을 통해 확인. (델파이 5)
흰색 점 : 거리를 벗어난 셸
검은 점 : 거리 이내로 판단된 셸
회색 점 : 사각영역이므로 거리판단을 생략하고 무조건 추출한 셸