지난 회차 게시물에서는 2차원 데이터를 이미지의 형태로 표출하면서 화소값의 높낮이에 따른 명암 및 그림자 효과를 구현하기 위하여 IDL의 OG(Object Graphics) 체계 기반으로 2차원 데이터를 서피스(Surface) 객체로 구현하고 여기에 광원(Light Source) 객체를 추가하여 이용하는 예제를 살펴본 바 있습니다. 일단 지난 회차에서 작업했던 내용을 그대로 가져와서 계속 작업을 이어나가기로 하겠습니다. 그 내용은 다음과 같습니다.
dd = 0.02
x = [-5:5:dd]#MAKE_ARRAY(10/dd+1, VALUE=1)
y = [-5:5:dd]##MAKE_ARRAY(10/dd+1, VALUE=1)
z = 5*((x^2+y^2)^0.3+SIN((x^2+y^2)*0.5))
HELP, z
PRINT, MIN(z), MAX(z)
oWin = OBJ_NEW('IDLgrWindow', DIMENSIONS=[500, 500])
oView = OBJ_NEW('IDLgrView', VIEWPLANE_RECT=[-0.5, -0.5, 1, 1])
oModel = OBJ_NEW('IDLgrModel')
oSurface = OBJ_NEW('IDLgrSurface', z, STYLE=2, SHADING=1, COLOR=[0, 255, 255])
oModel -> Add, oSurface
oSurface -> GetProperty, XRANGE=xrn, YRANGE=yrn, ZRANGE=zrn
xs = NORM_COORD(xrn)
xs[0] = xs[0]-0.5
ys = NORM_COORD(yrn)
ys[0] = ys[0]-0.5
zs = NORM_COORD(zrn)
zs[0] = zs[0]-0.5
oSurface -> SetProperty, XCOORD_CONV=xs, YCOORD_CONV=ys, ZCOORD_CONV=zs
oLight = OBJ_NEW('IDLgrLight', TYPE=2, LOCATION=[0, 0, 10])
oModel-> Add, oLight
oView -> Add, oModel
oWin -> Draw, oView
이 내용에서는 가상의 2차원 데이터를 서피스 객체로 구현하고 광원 객체가 원점의 상공에 위치하도록 하였습니다. 일단 이 내용을 실행하여 얻게 되는 그림은 다음과 같습니다.

여기까지는 지난 회차에서 이미 했던 내용입니다. 또한 광원의 위치를 적절히 옮겨서 명암 및 그림자가 다르게 보이도록 하는 방법도 이미 지난 회차에서 언급한 바 있습니다. 그러면 이번에는 광원의 위치를 순차적으로 조금씩 이동시켜가면서 그 변화를 확인해보기로 합니다. 이를 위해서는 반복형 구문을 사용하여 광원 객체의 위치에 해당되는 LOCATION 속성을 변화시키면 되는데, 이를 위하여 다음과 같은 내용을 추가해봅시다.
FOR j = 1, 100 DO BEGIN
oLight -> SetProperty, LOCATION=[j/10., 0, 10]
oWin -> Draw, oView
WAIT, 0.1
ENDFOR
이 내용은 광원의 Z 좌표는 그대로 두면서 X 좌표를 0부터 10까지 0.01씩 100회에 걸쳐 이동시키는 반복형 작업입니다. 이러한 내용을 실행하면 광원이 그림의 중심으로부터 X축의 (+) 방향 즉 동쪽 방향으로 서서히 이동하게 됩니다. 그러면서 그 명암이 서서히 변화하는 모습을 볼 수 있게 됩니다. 그리고 이번에는 바로 위의 내용을 다음과 같이 수정하여 다시 실행해봅시다.
FOR j = 1, 100 DO BEGIN
oLight -> SetProperty, LOCATION=[0, j/10., 10]
oWin -> Draw, oView
WAIT, 0.1
ENDFOR
이 내용은 광원의 Z 좌표는 그대로 두면서 Y 좌표를 0부터 10까지 0.01씩 100회에 걸쳐 이동시키는 반복형 작업입니다. 이러한 내용을 실행하면 광원이 그림의 중심으로부터 Y축의 (+) 방향 즉 북쪽 방향으로 서서히 이동하게 됩니다. 그러면서 그 명암이 서서히 변화하는 모습을 볼 수 있게 됩니다. 참조를 위하여 이러한 변화의 모습을 캡쳐한 동영상들을 아래에 첨부합니다.
https://youtube.com/shorts/4z9_wPbewhk?feature=share
- YouTube
www.youtube.com
https://youtube.com/shorts/mcHxUptmOpQ?feature=share
- YouTube
www.youtube.com
그러면 이번에는 새로운 2차원 자료를 사용해보기로 합니다. 이번에 사용할 예제 데이터는 IDL의 설치 디렉토리에 있는 marbells.dat라는 파일을 RESTORE 명령으로 복원시켜서 가져오면 됩니다. 먼저 이 과정은 다음과 같이 진행합니다.
file = FILEPATH('marbells.dat', SUBDIRECTORY=['examples', 'data'])
RESTORE, file
z = TEMPORARY(elev)
HELP, z
PRINT, MIN(z), MAX(z)
여기서 사용된 marbells.dat라는 파일은 확장자가 .dat이긴 하지만 사실은 .sav 파일입니다. 즉 IDL에서 데이터를 파일로 저장할 때 사용하는 방식으로 생성되어 제공되는 파일입니다. 따라서 위와 같이 RESTORE 명령을 사용하여 파일 내 데이터를 복원하면 elev라는 2차원 배열을 얻게 됩니다. 그리고 이후의 과정은 어차피 앞서 제시되었던 예제 코드의 내용을 그대로 따라갈 것이므로 데이터 배열이 z가 되도록 하기 위하여 TEMPORAY 함수를 사용하여 elev의 내용을 그대로 z로 옮기고 elev는 소멸시켰습니다.
어쨌든 이번에 사용될 새로운 데이터 z는 350x450의 구조를 가지며 값들의 범위는 2666~4241입니다. 실제로 이 데이터는 지형고도 값들이기 때문이 값들의 단위는 m입니다. 그러면 데이터의 형태를 보기 위하여 먼저 다음과 같이 NG 체계에서 이미지 및 서피스의 형태로 표출해보면 그 과정 및 표출 그림들은 다음과 같습니다.
win_i = WINDOW(DIMENSIONS=[500, 500], /NO_TOOLBAR)
i = IMAGE(z, RGB_TABLE=0, MARGIN=0, /CURRENT)
win_s = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)
i = SURFACE(z, COLOR='gray', MARGIN=0.18, /CURRENT)


위의 이미지 형태로 표출된 그림에서 밝은 부분이 고도가 높은 지형이고 어두운 부분이 고도가 낮은 지형에 해당됩니다. 즉 산악 지역의 산등성이 및 골짜기 지역에 해당된다고 볼 수 있으며, 이러한 형태는 서피스 그림에서도 확인할 수 있습니다. 그러면 이제는 이 데이터를 OG 체계에서 서피스 객체로 표출하는 과정으로 넘어갑시다. 그 과정은 다음과 같이 진행합니다.
oWin = OBJ_NEW('IDLgrWindow', DIMENSIONS=[500, 500])
oView = OBJ_NEW('IDLgrView', VIEWPLANE_RECT=[-0.5, -0.5, 1, 1])
oModel = OBJ_NEW('IDLgrModel')
oSurface = OBJ_NEW('IDLgrSurface', z, STYLE=2, SHADING=1, COLOR=[255, 255, 0])
oModel -> Add, oSurface
oSurface -> GetProperty, XRANGE=xrn, YRANGE=yrn, ZRANGE=zrn
xs = NORM_COORD(xrn)
xs[0] = xs[0]-0.5
ys = NORM_COORD(yrn)
ys[0] = ys[0]-0.5
zs = NORM_COORD(zrn)
zs[0] = zs[0]-0.5
oSurface -> SetProperty, XCOORD_CONV=xs, YCOORD_CONV=ys, ZCOORD_CONV=zs
oLight = OBJ_NEW('IDLgrLight', TYPE=2, LOCATION=[0, 0, 10])
oModel-> Add, oLight
oView -> Add, oModel
oWin -> Draw, oView
위의 내용 자체는 어차피 앞서 제시되었던 것과 거의 동일합니다. 다만 새로운 데이터이므로 색상만 [255, 255, 0]으로 변경하였습니다. 표출된 그림을 보면 다음과 같습니다.

앞서 했던 것과 마찬가지로 여기서도 광원은 원점 부분(그림의 정가운데)의 상공에 위치하여 빛을 아래로 내리쬐는 상태입니다. 그러면 이전 회차 게시물에서와 마찬가지로 광원의 위치를 이리저리 옮겨보겠습니다. 먼저 광원을 중심으로부터 X축의 (+) 방향으로 이동시키고 다시 실행해보면 그 결과는 다음과 같습니다.
oLight = OBJ_NEW('IDLgrLight', TYPE=2, LOCATION=[10, 0, 10])

여기서는 빛이 오른쪽에서 왼쪽으로 향하는 방향으로 비추기 때문에 그림자가 왼쪽 방향으로 형성되는 것을 볼 수 있습니다. 그리고 이번에는 광원을 중심으로부터 Y축의 (+) 방향으로 이동시켜서 다시 실행해보면 그 결과는 다음과 같습니다. 여기서는 빛이 위쪽에서 아래쪽으로 향하는 방향으로 비추기 때문에 그림자가 아래쪽 방향으로 형성되는 것을 볼 수 있습니다.
oLight = OBJ_NEW('IDLgrLight', TYPE=2, LOCATION=[0, 10, 10])

이번에는 서두에서 했던 것처럼 광원의 위치를 중심으로부터 특정 방향으로 순차적으로 조금씩 이동시켜가면서 그 변화를 확인해보기로 합니다. 이를 위해서는 반복형 구문을 사용하여 광원 객체의 위치에 해당되는 LOCATION 속성을 변화시키면 되는데, 이를 위하여 다음과 같은 내용을 추가하여 실행해봅시다.
FOR j = 1, 100 DO BEGIN
oLight -> SetProperty, LOCATION=[j/10., 0, 10]
oWin -> Draw, oView
WAIT, 0.1
ENDFOR
이 내용은 광원의 Z 좌표는 그대로 두면서 X 좌표를 0부터 10까지 0.01씩 100회에 걸쳐 이동시키는 반복형 작업입니다. 이러한 내용을 실행하면 광원이 그림의 중심으로부터 X축의 (+) 방향 즉 동쪽 방향으로 서서히 이동하게 됩니다. 그러면서 그 명암 및 그림자가 서서히 변화하는 모습을 볼 수 있게 됩니다. 그리고 이번에는 바로 위의 내용을 다음과 같이 수정하여 다시 실행해봅시다.
FOR j = 1, 100 DO BEGIN
oLight -> SetProperty, LOCATION=[0, j/10., 10]
oWin -> Draw, oView
WAIT, 0.1
ENDFOR
이 내용은 광원의 Z 좌표는 그대로 두면서 Y 좌표를 0부터 10까지 0.01씩 100회에 걸쳐 이동시키는 반복형 작업입니다. 이러한 내용을 실행하면 광원이 그림의 중심으로부터 Y축의 (+) 방향 즉 북쪽 방향으로 서서히 이동하게 됩니다. 그러면서 그 명암 및 그림자가 서서히 변화하는 모습을 볼 수 있게 됩니다. 참조를 위하여 이러한 변화의 모습을 캡쳐한 동영상들을 아래에 첨부합니다.
https://youtube.com/shorts/CcmGy-qN4pc?feature=share
- YouTube
www.youtube.com
https://youtube.com/shorts/YotXOiV3Gbk?feature=share
- YouTube
www.youtube.com
지금까지 살펴본 바와 같이 2차원 데이터 특히 고도값들로 구성된 지형 데이터에 대하여 광원을 적용하여 명암 및 그림자를 구현하기 위해서는 OG(Object Graphics) 체계 기반으로 데이터를 서피스 객체의 형태로 구현하고 여기에 광원 객체를 추가하여 적절한 방식으로 활용하면 됩니다. 물론 OG 체계에서 구현되는 서피스 객체의 시선 방향을 디폴트 상태로 두면 위에서 아래로 내려다보는 형태로 마치 이미지인 것처럼 보이게 된다는 것을 유념해야 합니다. 또한 광원을 적용하는데 있어서는 광원 객체의 위치, 속성 등에 대한 세부적인 설정에 따라서 그 결과가 달라질 수 있다는 것도 함께 염두에 두어야 합니다. 이러한 작업을 위하여 사용된 IDL OG 체계의 IDLgrSurface 및 IDLgrLight 클래스에 대한 자세한 내용은 IDL 도움말에서 IDL > Routines (by topic) > Object Class Library 섹션을 참조하거나 또는 해당 웹페이지 링크를 참조하시면 됩니다.
* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > Object Graphics' 카테고리의 다른 글
| 이미지(Image)에 대한 광원 효과 적용 [1] (0) | 2026.01.28 |
|---|---|
| Wire Frame 3D Sphere의 구현 [2] (0) | 2016.10.24 |
| Wire Frame 3D Sphere의 구현 [1] (0) | 2016.10.21 |
| 3D 폴리곤 가시화 예제 (Stanford bunny) (0) | 2015.06.01 |
| 고리형(Ring Shaped) 폴리곤을 구현해봅시다 (0) | 2014.08.29 |