IDL/New Graphics

NG 체계에서 서피스(Surface)와 타 그래픽 요소의 중첩 표출 [2]

이상우_IDL 2018. 12. 21. 17:00
728x90

* 지난 회 내용에서 계속 이어집니다.


지난 회에서는 Surface 형태의 3차원적 그래픽을 표출한 상태에서 Image 또는 Contour를 XY 평면의 형태로 중첩하여 함께 표출하는 방법을 Surface & Image, Surface & Contour 두가지 방식으로 나누어 소개하였습니다. 오늘은 Surface & Map의 방식에 관하여 알아보고자 합니다. 즉 Surface 형태의 3차원적 그래픽을 표출한 상태에서 지도(Map) 그림을 XY 평면의 형태로 중첩하여 표출하는 방법입니다. 일단 미리 좀 말씀을 드리자면, 원래는 이러한 중첩 표출도 간편하게 구현이 가능하면 좋을텐데 안타깝게도 현실은 그렇지가 않습니다. 그래서 약간의 우회적인 방법이 동원되어야 하기 때문에, 이러한 방법에 관해서도 함께 소개하겠습니다. 우선 예제 데이터는 지난 회에서 사용했던 것과 같습니다. 그래서 다음과 같이 예제 데이터에 대한 정의부터 먼저 하겠습니다.


xx = FINDGEN(400)/40+122

yy = FINDGEN(400)/40+33

data = HANNING(400, 400)*100

add = FLTARR(400, 400)

add[240, 40] = HANNING(150, 150)*50

data = data + add

HELP, data

PRINT, MIN(data), MAX(data)


이와 같이 400x400의 배열 구조를 갖는 2차원 데이터를 사용합니다. 여기서 data라는 배열로 정의된 데이터의 값의 범위는 0~100입니다. 그리고 이 데이터는 경도 방향으로 동경 122~132도 그리고 위도 방향으로 북위 33~43도의 범위에 존재합니다. 그래서 각 방향 격자점들이 xx 및 yy라는 1차원 배열로 정의되어 있습니다. 그러면 먼저 다음과 같이 그래픽 창을 열고 서피스의 형태로 이 데이터를 먼저 표출합니다.


win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)

sf = SURFACE(data, xx, yy, TEXTURE_IMAGE=data, RGB_TABLE=73, $

  XRANGE=[122, 132], YRANGE=[33, 43], /CURRENT)


지난 회에서 Surface & Image, Surface & Contour의 경우와 비슷한 흐름으로 작업을 진행한다면, 이제 이 시점에서 지도 표출 과정이 나와야 합니다. NG 체계에서 지도를 표출하는 방법은 제가 이 블로그에서 자주 소개를 했었는데, 이 방법에 의하면 항상 MAP 함수를 먼저 사용한 다음 MAPCONTINENTS 함수를 이어서 사용했었습니다. 따라서 이 방식으로 지도를 서피스의 XY 평면상에 표출할 수 있으리라 짐작해볼 수 있습니다. 이를 위하여 다음과 같이 MAP, MAPCONTINENTS 함수를 사용해 봅시다.


m = MAP('Geographic', LIMIT=[33, 122, 43, 132], /OVERPLOT)

mc = MAPCONTINENTS(FILL_COLOR='gold', /HIRES)


이렇게 하여 표출된 그림은 다음과 같습니다.



그런데 보시는 것처럼 뭔가 좀 이상합니다. 분명 우리가 기대했던 결과는 아닌 것 같습니다. 사실 지도 그림 자체는 바닥에 표출되어 있습니다. 그래서 서피스를 마우스로 드래그해서 돌려보면 다음과 같이 밑바닥에 표출된 지도가 보이긴 합니다.



하지만 그럼에도 불구하고 이 결과는 몇가지 문제점들을 안고 있습니다. 첫번째 문제점은 지도가 표출될 XY 평면의 Z축 위치를 제어할 방법이 없다는 것입니다. 왜냐하면 IMAGE나 CONTOUR 함수와 달리 MAP 함수에는 ZVALUE 속성이 지원되지 않습니다. 따라서 평면이 위치할 높이를 제어할 수 없기 때문에 항상 평면이 맨 밑바닥에만 위치하게 됩니다. 두번째 문제점은 지도를 중첩하면서 서피스 그림의 Z축이 아예 사라져버리고 X, Y축들의 경우도 눈금 문자들이 사라지는 등 축들 전반에 걸쳐 나타나는 문제들입니다. 그림을 보시면 금방 알 수 있습니다. Z축의 경우는 실제로는 존재는 하는데, 이상하게도 눈에 보이도록 표출되지는 않는 현상입니다. 어쨌든 이러한 문제점들은 근본적으로는 IDL의 NG 체계에서는 MAP 관련 기능이 3차원 그래픽 공간에 제대로 대응하지 못하기 때문에 벌어지는 현상이라고 보면 됩니다. 즉 지도를 일반적인 평면상의 그림으로 표출할 경우에는 전혀 문제가 없지만, 지금처럼 3차원 공간상에 평면의 형태로 지도를 구현하는데 있어서는 몇가지 문제점들이 분명히 존재한다는 것입니다. 따라서 현 시점에서는 약간 우회적인 방법을 사용해야 우리가 원하는 표출이 가능한 상황이라고 보시면 됩니다. 따라서 이 방법을 지금부터 소개하겠습니다. 그 과정은 다음과 같습니다.


win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)

sf = SURFACE(data, xx, yy, TEXTURE_IMAGE=data, RGB_TABLE=73, $

  XRANGE=[122, 132], YRANGE=[33, 43], $

  XTICKINTERVAL=1, YTICKINTERVAL=1, /CURRENT)

mg = MAPGRID(LONGITUDE_MIN=122, LONGITUDE_MAX=132, $

  LATITUDE_MIN=33, LATITUDE_MAX=43, COLOR='black', $

  LABEL_POSITION=0)

m = MAP('Geographic', LIMIT=[33, 122, 43, 132], /OVERPLOT)

mc = MAPCONTINENTS(FILL_COLOR='gold', /HIRES)


이 내용을 보면 앞서 우리가 했던 작업과는 차이가 좀 있습니다. 가장 중요한 차이점은 MAPGRID 함수를 가장 먼저 사용한 것입니다. 그런 다음에서야 MAP과 MAPCONTINENTS 함수가 사용되고 있습니다. MAPGRID 함수를 먼저 사용한 것은 지도를 중첩할 때 서피스의 Z축이 사라지는 등 서피스 자체의 축들의 표출에 있어서 나타났던 여러가지 문제점들을 방지하고, 지도 자체의 X 및 Y 방향 축들도 제대로 보이게 하기 위한 것입니다. 그러나 이것만으로는 아직은 문제점들이 완전히 해결된 것은 아닙니다. 지도가 표출된 평면이 서피스의 밑바닥에서만 존재하는 문제점은 여전히 남아 있습니다. 따라서 이러한 문제점까지 마저 해결하기 위하여 다음과 같은 과정을 추가하였습니다.


zticks_orig = sf.ZTICKNAME

zoffset = 110

data_new = data-zoffset

sf.SetData, data_new

sf.zrange = [MIN(data_new), MAX(data_new)]

sf.ztickname = zticks_orig

sf.ASPECT_Z = 0.07


이 내용은 데이터의 Z축 범위에 대하여 의도적으로 편차(offset)를 추가한 다음, 나중에 Z축에 대하여 이 편차를 보정한 라벨값들로 재설정하는 과정입니다. 여기서 zoffset이란 변수가 이 편차에 해당되는데, 이 값이 위와 같이 110일 경우에는 Z축의 높이 110에 지도 평면이 위치하게 됩니다. 이 값은 원하는 대로 조정하면 됩니다. 전체적으로는 Z축의 원래의 눈금값들을 먼저 저장하고, zoffset만큼 높이가 조정된 새로운 2차원 데이터를 정의하여 서피스 그림의 데이터를 대체한 후, Z축의 범위를 이 새로운 데이터에 맞춰주고, 그 대신 축의 눈금 숫자들은 원래의 눈금 숫자들로 대체하는 일련의 과정이라고 보면 됩니다. 조금 복잡하게 보이는 것은 사실이지만, 현재로서는 이게 최선인 것 같습니다. 마지막 줄에 있는 ASPECT_Z 설정은 서피스 그림을 약간 납작하게 해주면 보기가 더 좋은 것 같아서 추가하였습니다. 이러한 처리까지 다 거치면 다음과 같은 그림을 얻을 수 있습니다.



그리고 MAPCONTINENTS에서 다음과 같이 투명도 속성까지 설정하면 다음과 같이 육지 부분이 약간 투명하게 처리된 그림을 얻는 것도 가능합니다.


mc = MAPCONTINENTS(FILL_COLOR='gold', /HIRES, TRANSPARENCY=30)



그래서 정리를 해본다면, 서피스와 지도 그림을 함께 중첩 표출하는데 있어서는 현 시점에서는 이와 같은 방법을 사용하는 것이 최선으로 보입니다. 사실 지도의 표출 기능이 서피스로 구현되는 3차원 그래픽 체계와 완벽하게 연동되지 않기 때문에, 이렇게 약간 복잡해 보일 수도 있는 우회적인 방법을 사용할 수 밖에 없었습니다. 유저의 입장에서 본다면 Surface & Image, Surface & Contour 형태의 표출이 지난 회에 봤던 것처럼 비교적 간단한 코딩만으로 구현이 가능하다면 Surface & Map 형태의 표출도 그럴 것이라고 생각하는 것이 자연스러울 것인데, 실제로는 그렇지가 않습니다. 이것은 버그라고 하기보다는 유저 편의성이라는 관점에서 볼 때 좀 아쉬운 부분이라고 생각이 됩니다. 이러한 이슈에 관해서는 본사에서도 인지를 하고 있으므로 향후에 뭔가 개선이 있길 기대해 봅니다.

LIST