오늘 소개할 내용은 3차원 큐브 형태의 구조를 갖는 볼륨(Volume) 데이터에 해당되는 3차원 배열이 있을 때, 그 데이터에 대한 등위면(Isosurface)을 NG 체계에서 표출하는 방법에 관한 것입니다. 등위면이라고 하는 것은 3차원 데이터 내에서 동일한 값을 갖는 부분들을 면(Surface)의 형태로 이어주는 형태라고 볼 수 있는데, 마치 2차원 데이터의 경우로 보자면 등위선(Contour)과 비슷한 느낌입니다. 즉 등위선의 3차원 버전이라고 보면 됩니다.
원래 3차원 큐브 데이터를 볼륨 형태로 가시화하는데 있어서는 VOLUME 함수를 이용하면 됩니다. 이 방법에 관해서는 제가 예전에 관련 게시물들(게시물 1, 게시물 2)을 올린 바 있습니다. 다만 오늘은 볼륨 형태의 표출보다도 등위면의 표출 방법에 촛점을 맞추게 되는데요. 사실 등위면의 표출 과정에서도 일단 VOLUME 함수를 이용하게 됩니다. 물론 VOLUME 함수 외에도 다른 기능들이 추가적으로 사용되어야 합니다. 그러면 지금부터 그 과정을 예제와 함께 살펴보겠습니다. 먼저 예제 데이터는 앞서 언급한 이전 게시물들에서 사용했던 데이터를 그대로 사용합니다. 일단 그 과정은 다음과 같습니다.
ifile = FILEPATH('jet.dat', SUBDIR=['examples', 'data'])
data = READ_BINARY(ifile, DATA_DIMS=[81, 40, 101])
HELP, data
PRINT, MIN(data), MAX(data)
이와 같이 먼저 예제 데이터를 불러옵니다. 여기서 사용된 데이터 파일 jet.dat는 IDL 설치 디렉토리에 기본적으로 제공되는 파일로서, 81x40x101의 구조를 갖는 3차원 큐브형 데이터를 담고 있는 바이너리(binary) 파일입니다. 따라서 이러한 바이너리 파일을 읽기 위해서 READ_BINARY 함수를 사용하였습니다. 이 파일로부터 읽어온 데이터를 data라는 배열로 담았고, 이 data 배열에 관하여 출력된 기본 정보들은 다음과 같습니다.
DATA BYTE = Array[81, 40, 101]
0 240
이와 같이 배열 내 값들의 범위는 0~240임을 알 수 있습니다. 그러면 다음과 같이 VOLUME 함수를 사용하여 이 데이터를 볼륨 형태로 먼저 가시화합니다. 그 과정은 다음과 같습니다.
win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)
vol = VOLUME(data, ASPECT_RATIO=1, MARGIN=0.15, /CURRENT)
표출된 모습은 다음 그림과 같습니다.
이와 같이 볼륨의 형태로 표출되었으며 컬러테이블은 그냥 디폴트인 0번 흑백 컬러테이블이 적용된 상태입니다. 물론 이 데이터에 대한 등위면(Isosurface)을 표출하는 일이 아직 남았습니다. 이를 위해서는 먼저 등위면을 구하기 위한 기준값을 정하고 그 값에 대한 등위면 데이터를 산출해야 합니다. 사실 등위면이라는 것은 그래픽적으로는 폴리곤(Polygon)에 해당됩니다. 그리고 폴리곤을 표출하기 위해서는 그 폴리곤을 구성하는 꼭지점들(vertices) 및 연결성(connectivity) 정보가 반드시 필요합니다. 즉 등위면을 구할 기준값이 주어진 상태에서 그 등위면에 대한 이러한 정보들을 구체적으로 산출해야 한다는 의미인데요. IDL에서는 3차원 큐브 데이터에 대하여 등위면 폴리곤의 데이터를 산출해주는 역할을 하는 명령이 두 종류가 있습니다. 바로 ISOSURFACE 및 SHADE_VOLUME 명령입니다. 일단 여기서는 SHADE_VOLUME 명령을 사용해보겠습니다. 그 과정은 다음과 같습니다.
val = 120
SHADE_VOLUME, data, val, verts, conn
HELP, verts, conn
이와 같이 문법 자체는 비교적 간단합니다. 여기서는 120이라는 값을 기준값으로 사용하였습니다. 그래서 SHADE_VOLUME 명령의 첫번째 인수는 3차원 데이터 배열이 되고, 두번째 인수는 기준값이 됩니다. 그리고 세번째 및 네번째 인수인 verts와 conn은 내가 돌려받을 결과입니다. 즉 등위면 폴리곤을 구성하는 꼭지점들(vertices) 정보가 verts라는 이름으로 전달되고 연결성(connectivity) 정보가 conn이라는 이름으로 전달되도록 한 것입니다. HELP에 의하여 출력된 내용을 보면 다음과 같습니다.
VERTS FLOAT = Array[3, 13022]
CONN LONG = Array[66861]
이 내용의 의미는 등위면 폴리곤을 구성하는 꼭지점들의 총 갯수가 13022개이고 그 꼭지점들에 대한 연결성 정보의 양이 66861개라는 것입니다. 하여간 중요한 것은 이 정보를 갖고 폴리곤을 표출하는 작업이 될 것입니다. 이 과정에서는 POLYGON 함수가 사용되어야 하는데, 이 함수에 투입할 인수값들을 문법에 맞게 정의하는 과정도 함께 필요합니다. 그 과정은 다음과 같습니다.
vol.HIDE = 1
vtx = REFORM(verts[0, *])
vty = REFORM(verts[1, *])
vtz = REFORM(verts[2, *])
clr = 'deep sky blue'
isosurf = POLYGON(vtx, vty, vtz, CONNECTIVITY=conn, $
FILL_COLOR=clr, COLOR=clr, /DATA, CLIP=0, TARGET=vol)
여기서는 먼저 앞서 표출했던 볼륨 개체인 vol에 대하여 HIDE 메서드를 사용하여 볼륨의 모습을 숨겼습니다. 그 이유는 바로 이어서 표출될 등위면 폴리곤이 잘 보이도록 하기 위함입니다. 볼륨 그래픽이 존재하는 상태에서는 폴리곤이 제대로 보이기 힘들기 때문입니다. 그리고 POLYGON 함수에서는 폴리곤을 구성하는 꼭지점들의 X, Y, Z 좌표들을 각각 나누어서 투입해야 하기 때문에 위와 같이 verts로부터 vtx, vty, vtz를 따로 추출하였습니다. 그리고 연결성 정보인 conn인 CONNECTIVITY 속성에 그대로 투입하면 됩니다. 그 외에도 TARGET 속성을 사용함으로써 이 폴리곤이 표출될 기본 공간이 앞서 VOLUME 함수로 가시화된 XYZ 공간임을 명확히 하였습니다. 또한 /DATA 키워드를 사용함으로써 폴리곤 데이터의 좌표값들이 VOLUME 함수로 표출된 XYZ 데이터 좌표계를 기반으로 하도록 하였습니다. 이러한 과정에 의하여 표출된 등위면의 모습은 다음 그림과 같습니다.
이 모습은 기준값을 120으로 설정한 경우입니다. 다른 값으로 설정하면 당연히 다른 모습이 됩니다. 만약 기준값을 80으로 낮출 경우의 모습은 다음과 같습니다.
그리고 기준값을 160으로 높일 경우의 모습은 다음과 같습니다.
이렇게 표출된 등위면 그림은 마우스 드래그에 의하여 이리저리 회전하면서 볼 수도 있습니다. 이를 위해서는 XYZ 축 공간 내에서 등위면 폴리곤을 살짝 피해서 빈 공간에 마우스 포인터를 올려놓고 마우스 왼쪽 버튼을 몇번 눌러주면 커서가 둥글게 회전하는 형태로 변하게 되는데 이 때 왼쪽 버튼을 누른 상태로 이리저리 드래그해주면 됩니다. 직접 해보시기 바랍니다. 다만 등위면을 구성하는 꼭지점들의 갯수가 많을수록 드래그 회전이 약간 버벅거릴 수도 있습니다. 물론 그 버벅거림의 정도는 컴퓨터의 스펙에 따라 다를 수 있습니다. 만약 심하게 버벅거릴 경우에는 컴퓨터의 교체를 심각하게 고민해봐야 할 수도 있습니다.
그리고 앞서 제가 SHADE_VOLUME 명령 외에 ISOSURFACE 명령도 언급을 했었는데요. 만약 SHADE_VOLUME 대신 ISOSURFACE 명령을 사용하고자 한다면 SHADE_VOLUME 명령이 사용되었던 부분만 다음과 같은 내용으로 대체하면 됩니다.
ISOSURFACE, data, val, verts, conn
다만 제가 테스트해본 바로는 ISOSURFACE 명령에 의하여 얻어진 폴리곤 데이터의 꼭지점 갯수가 SHADE_VOLUME을 사용할 때보다 훨씬 더 많았습니다. 사실 눈으로 보기에는 큰 차이가 느껴지진 않기 때문에 꼭지점 갯수가 적은 쪽이 더 나을 것 같긴 합니다. 그래야 마우스 드래그로 이리저리 회전시켜서 보기가 더 원활하기 때문입니다. 두 명령의 결과가 서로 이러한 차이가 나는 이유는 저도 잘 모르겠습니다. 하여간 상황에 맞게 선택하여 사용하면 될 것 같습니다.
'IDL > New Graphics' 카테고리의 다른 글
등위선(Contour)과 컬러바(Colorbar) (0) | 2021.09.27 |
---|---|
BOXPLOT 함수 소개 (0) | 2021.09.07 |
NG 체계 플롯에서 타이틀 문자의 세부 설정 (0) | 2021.08.09 |
NG 체계의 IMAGE 함수를 이용한 표출시 유의사항 (0) | 2021.06.02 |
NG 체계에서 ConvertCoord 메서드의 활용 (0) | 2021.05.04 |