IDL/Object Graphics

Object Graphics in IDL [21]

이상우_IDL 2011. 1. 18. 00:17
728x90

객체의 변환 (Transforming Objects)


지금까지는 주로 그래픽 디바이스 객체 또는 뷰 객체와 같이, 세부적인 그래픽 컨텐츠를 포함하는 그릇의 역할을 하는 객체들에 대한 내용이 주를 이루었다. 이번 시간부터는 아마 약 4~5회에 걸쳐서, 그보다 한 단계 아래로 내려가서 주로 모델 객체와 관련된 내용을 다루게 된다. 클래스들에 관한 내용에서 한번 언급을 했지만, 이 모델 객체 역시 어느 정도는 추상적으로 느껴지는 개념이긴 하다. 그러나 실제로 우리가 구현하고자 하는 각종 하위 그래픽 객체들이 우리의 눈에 보이려면 이들은 무조건 어떤 모델 객체안에 포함이 되어야 한다. 예를 들어, 이미지에 해당되는 이미지 객체가 있다고 하면, 이 객체를 포함하는 모델 객체가 반드시 있어야만 한다. 그래야 이 이미지가 실제로 우리의 눈에 보일 수 있다. 모델 객체에 포함되지않은 하위 그래픽 객체는 절대로 우리 눈에 보이지않는다는 사실을 먼저 유념하길 바란다.

모델 객체는 단순히 하위 그래픽 객체들을 포함하는 역할외에도, 이러한 객체들에 대한 이동, 회전, 확대/축소 등의 역할을 담당한다. 이것은 모델 객체마다 자체적으로 변환행렬(Transformation Matrix)를 내장하고 있기 때문이다. 하나의 모델 객체안에 포함된 모든 하위 그래픽 객체들은 반드시 이 변환행렬에 의하여 제어된다. 이 변환행렬은 모델 객체의 TRANSFORM이라는 속성으로 주어지며 4X4의 크기를 갖는다. 모델 객체의 변환행렬은 기본적으로는 다음과 같은 단위행렬의 형태를 갖는다.

물론 이 속성은 생성시에 임의로 설정 가능하고, 생성 후에도 SetProperty 메서드를 사용하여 변경이 가능하다. 생성시에 tmatrix라는 이름의 4X4 행렬을 변환행렬로서 설정하고자 한다면 다음과 같이 해준다.

myModel = OBJ_NEW(‘IDLgrModel’, TRANSFORM=tmatrix)

앞서 언급된 이동, 회전, 확대/축소 등의 조작은 기본적으로는 이와 같은 변환행렬의 원소값을 적절히 변경함으로써 이루어진다. 하지만 변환행렬의 원소값 자체를 직접 변경하는 것은 직관적이지 못하고 복잡하므로, 이를 위한 Translate, Rotate, Scale과 같은 메서드들을 사용하는 경우가 일반적이다.

여기서 유념해야 할 사항은,  이와 같은 메서드들은 반드시 모델 객체에 대해서만 적용된다는 점이다. 따라서 두 개의 하위 그래픽 객체에 대하여 따로따로 이러한 메서드를 적용하기 위해서는, 두 객체를 각각 서로 다른 모델 객체안에 넣어서 각 모델 객체를 따로 취급해야 한다. 하나의 모델 객체안에 있는 하위 그래픽 객체들은 무조건 그 모델 객체에 속성으로 부여된 변환행렬의 지배를 받는다는 점을 명심하도록 한다.

이동(Translation)

말 그대로 모델 객체를 3차원 공간상에서 임의의 방향으로 일정 거리만큼 이동시키는 동작을 의미한다. 이러한 동작은 모델 객체에 대하여 Translate라는 메서드를 적용함으로써 이루어진다. 예를 들어, myModel이라는 모델 객체를 X축 방향으로 1만큼 이동을 시키고자 한다면 다음과 같이 하면 된다.

myModel -> Translate, 1, 0, 0

여기서 메서드 뒤에 나오는 세 개의 인자들은 각각 X, Y, Z 축 방향으로의 이동거리에 해당된다. 이렇게 단 한 줄로 간단하게 처리되는 작업이지만, 사실 그 속을 들여다보면 원래 이 모델 객체가 갖고 있는 변환행렬에 이동행렬을 곱해줘서 새로운 변환행렬을 생성하고 이를 새로운 속성으로 부여한 것이다. 어쨌든 내부적으로는 행렬곱이라는 연산과정이 숨어있다는 점을 참고적으로 알아두자.

회전(Rotation)

모델 객체를 특정한 방향을 갖는 축에 대하여 일정 각도만큼 회전시키는 동작을 의미한다. 이러한 동작은 모델 객체에 대하여 Rotate라는 메서드를 적용함으로써 이루어진다. 예를 들어, myModel이라는 모델 객체를 Y축에 대하여 원래 있던 위치로부터 90도의 각도만큼 회전시키고자 한다면 다음과 같이 하면 된다.

myModel -> Rotate, [0, 1, 0], 90

여기서 메서드 뒤에 나오는 첫번째 인자는 회전의 중심이 될 축의 벡터의 방향성분이다. Y축은 그 방향벡터가 [0, 1, 0]이 된다. 그리고 그 뒤에 나오는 인자는 회전할 각도를 degree 단위로 나타낸 것이다. 이 동작 역시 세부적으로 들여다보면 원래 이 모델 객체가 갖고 있는 변환행렬에 대하여 회전행렬을 곱해줘서 새로운 변환행렬을 생성하고 이를 새로운 속성으로 부여한 것이다.

확대/축소(Scaling)

모델 객체에 대하여 X, Y, Z 각 축 방향으로 스케일 조정을 가하는 동작을 의미한다. 쉽게 얘기하여 확대/축소라고 보면 된다. 다만 그 배율을 각 축 방향으로 설정해줘야 한다는 점을 기억해야 한다. 이러한 동작은 Scale이라는 메서드를 적용함으로써 이루어진다. 예를 들어, myModel이라는 모델 객체를 Y축에 대해서만 두 배로 확대하고자 한다면 다음과 같이 하면 된다.

myModel -> Scale, 1, 2, 1

여기서 메서드 뒤에 나오는 세 개의 인자들은 각각 X, Y, Z 축 방향의 배율에 해당된다. 이 예제에서는 Y축에 대해서만 배율 조정이 이루어지고, X 및 Z 축으로는 변동사항이 없으므로 1이라는 값이 주어졌음을 유의한다.

합성 변환 (Combined Transformation)

모델 객체는 기본적으로 다른 모델 객체를 포함할 수 있다는 것을 알고 있는가? 이 경우 두 모델 객체는 각각 나름대로의 변환행렬을 갖고 있을 것이다. 따라서, 하위에 포함된 모델 객체에 대한 변환행렬은 원래의 변환행렬에, 상위에서 포함하는 모델 객체의 변환행렬이 곱해진 형태가 될 것이다. 즉, 두 변환행렬의 합성(곱)으로 적용된다는 의미이다. 다음의 예를 살펴보자.

model_A = OBJ_NEW(‘IDLgrModel’, TRANSFORM=trans_A)

model_B = OBJ_NEW(‘IDLgrModel’, TRANSFORM=trans_B)

model_B -> Add, model_A

이 경우 model_A는 model_B에 포함되는 관계가 된다. 그러면 model_A는 원래 자신의 변환행렬인 trans_A에, 상위 모델 객체의 변환행렬인 trans_B까지 반영된 변환행렬을 최종적으로 갖게 된다. 즉, 두 행렬의 합성인 trans_A#trans_B이 변환행렬이 될 것이다. 따라서 model_A에 포함된 하위 그래픽 객체의 경우 이 합성된 변환행렬의 지배를 받게 된다. 하지만 이와 같은 방식으로 그래픽을 구현하는 경우는 그리 흔하지는 않으므로, 당분간은 너무 신경쓰지않아도 되지않을까 생각한다.

LIST

'IDL > Object Graphics' 카테고리의 다른 글

Object Graphics in IDL [23]  (0) 2011.01.31
Object Graphics in IDL [22]  (0) 2011.01.24
Object Graphics in IDL [20]  (0) 2011.01.11
Object Graphics in IDL [19]  (0) 2011.01.04
Object Graphics in IDL [18]  (0) 2010.12.31