============================================
사각영역에 숨겨진 작은 비밀 # 2
27 Nov, 2002
Written by Un-Wook
============================================
- 차례 -
1. 서문 2. CRect와 논리적 좌표계 3. CRect의 유용한 기능 4. 논리적 좌표계에서의 비사각영역 5. 비사각영역의 연산 6. 마치며
----------------------------- 1. 서문 -----------------------------
1회분으로 작성한 글은 잘 보셨는지요.?
처음 시작해보는 강좌여서 많이 서툴렀을거라고 생각되네요.
1회를 올리지도 않고 바로 2회를 동시에 올리게 되서 반응도 모르는 상황이지만
이왕 시작했으니 그냥 제맴대로 갈때까지 써보렵니다..
전강좌에서는 실용적인 측면을 예를 들어 논리적 좌표계에 대한 설명을 드렸고,
이번 강좌에서는 CRect 클래스와 더불어 이야기를 풀어 나가보려고 합니다.
CRect와 "논리적좌표계"의 상관관계를 풀어 나가보는게 이 글의 주제가 될 것 같네요.
CRect의 유용한 기능도 몇 가지 소개해드릴 거구요..
논리 좌표계이기때문에 발생하는 문제점에 대해서도 이야기 해보렵니다..
1회분을 읽지 않으시고 이 글을 읽으시면 조금 혼동 스러우실 테니.. 1회를 먼저 읽어주시기 바랍니다.
----------------------------- 2. CRect와 논리적 좌표계 -----------------------------
1회에서 설명했던 width= right-left 라는 규칙 (논리적 좌표계를 사용하는 규칙)은..
MFC 에 와서도 CRect라는 클래스에서 그대로 고수하게 됩니다.
아래 코드를 보시면
CRect rtBox(1, 1, 3, 3); int nWidth= rtBox.Width();
위의 코드를 돌려보면.. nWidth 로는 2 라는 값이 넘어오지요..
(1,1)~(3,3) 의 가로폭은 2라는 의미 이고..
rtBox은 "논리좌표계"상의 좌표값으로 초기화 한것이라고 볼 수 있습니다.
아래 코드도 보시면
CRect rtBox(1, 1, 3, 3); CPoint pt1= rtBox.TopLeft(); CPoint pt2= rtBox.BottomRight();
pt1 에는 1, 1 이 들어오고
pt2 에는 3, 3 이 잘 들어옵니다.. nWidth 가 2 인데도 이런 값이 넘어오는 걸 보면
이 경우에도 논리적 좌표값이 넘어온 것이지요.
여러가지 상황을 테스트 CRect 에 쳐박혀있는 값은 논리좌표계 상의 값이라고 결론내릴 수가 있습니다.
CRect 에 들어가있는 값이 논리좌표계라는 것이 중요합니다!!..
이 사각영역을 화면에 출력할때는 스크린과 일치하지 않는 다는 것은 제가 1편에서 빡터지게 설명해드렸슴니당..
가물가물 하시면 1편을 다시 읽어보세요.. 꼭...
논리좌표계의 의미를 꼭 이해하셔야 합니다.
------------------------- 3. CRect의 유용한 기능 -------------------------
본론을 말씀드리기 전에 CRect 의 기능 몇가지를 소개해 드리겠습니다.
(아직 모르시는 분들도 계실테니.. 집구 넘어가야 설명이 진행될것 같아요..)
### 여기서 첨부한 그림을 봐 주세요 ###
그림과 같이 2 개의 사각형이 차지하는 총 사각영역을 (첨부된 그림파일의 왼쪽 아래 처럼..)
이것을 얻어오려면 어떻게 해야할까요
2 개의 사각영역의 원소들을 모두 비교 검사하여 값을 얻어오면 되기야 되겠죠..
그런데 CRect 에서 그런 기능도 지원을 해주거든요..
오버로딩된 연산자중에 | (or) 연산자가 그기능을 해줍니다.
다음과 같은 코딩으로 원하던 값을 얻어올 수 있겠군요 그럼..
CRect rtBox1(1, 1, 3, 3); CRect rtBox2(2, 2, 5, 5); CRect rtBox3= rtBox1 | rtBox2;
rtBox3 에는 원하던 사각영역이 들어오게 됩니다.
혹은 첨부된 그림파일의 오른쪽 아래 그림처럼
두 사각영역의 교집합격인 영역을 얻어오려면
& (and) 연산자를 사용하시면 됩니다
CRect rtBox1(1, 1, 3, 3); CRect rtBox2(2, 2, 5, 5); CRect rtBox3= rtBox1 & rtBox2;
위와 같은 코딩으로 rtBox1 과 rtBox2 의 교집합 격인 사각영역이 rtBox3 에 얻어집니다.
편리하지요?
그밖에도 여러가지 연산자들이 오버로딩 되어있어.. 참 편리하답니다.
각각의 연산자 함수는 특정한 기능이 정의되어 있습니다.
CRect 의 편의 기능에 대한 강좌는 이니지만.. 참고루 MSDN의 내용을 뿌려봅니당..^^
operator LPCRECT Converts a CRect to an LPCRECT. operator LPRECT Converts a CRect to an LPRECT. operator = Copies the dimensions of a rectangle to CRect. operator == Determines whether CRect is equal to a rectangle. operator != Determines whether CRect is not equal to a rectangle. operator += Adds the specified offsets to CRect or inflates CRect. operator ?= Subtracts the specified offsets from CRect or deflates CRect. operator &= Sets CRect equal to the intersection of CRect and a rectangle. operator |= Sets CRect equal to the union of CRect and a rectangle. operator + Adds the given offsets to CRect or inflates CRect and returns the resulting CRect. operator ? Subtracts the given offsets from CRect or deflates CRect and returns the resulting CRect. operator & Creates the intersection of CRect and a rectangle and returns the resulting CRect. operator | Creates the union of CRect and a rectangle and returns the resulting CRect.
연산자 오버로딩은 중요한 거고 자주 등장하는 말이기도 하구요
아직 연산자 오버로딩을 모르셨다면 CPP 서적이나 다른 강좌를 참고 하시기를 바래요..
이 강좌가 오버로딩에 대한 이야기는 아니니까요..
------------------------------------ 4. 논리적 좌표계에서의 비사각영역 ------------------------------------
아래 부분 부터는 제가 궁극적으로 이야기 해 보고싶었던 내용입니다.
사실은 제가 아래와 같은 문제에 봉착한 것이 이 강좌를 쓴 계기가 되었어요..
비사각영역이라는 말이 괜히 거창해 보이는데 별 얘기 아닙니다..
(5, 5, 5, 5) 같은 사각영역은 과연 무엇을 의미할까요?..
픽셀 좌표계라면 점 하나의 사각형이라고 볼 수 있겠지만..
논리적 좌표계로 본다면 이것은 사각형이라고 볼 수 없습니다..
제가 1회 강좌에 그려서 첨부한 그림파일을 보시고 판단해 보세요.
논리적 좌표계에서 (5, 5, 5, 5) 는 사각영역이 아니라 그냥 無라는 의미입니다.
이것이 CRect 가 논리 좌표계를 이용한다는걸 역설해주고 있는 부분이구요.
------------------------ 5. 비사각영역의 연산 ------------------------
CRect 에 (5, 5, 5, 5)라고 영역을 정의하고 연산할경우..
사각형으로 취급하지 않기 때문에 연산후에 원하는 결과를 얻어오지 못할 것입니다.
궁금하신 분들은 아래의 두가지 코드를 직접 돌려보시기 바랍니다.
rtBox3 가 각각의 경우에서 어떤 값을 갖게 되는지..
예1) CRect rtBox1(1, 1, 3, 3); CRect rtBox2(5, 5, 6, 6); // (5, 5, 6, 6) -> 정상적인 사각영역 CRect rtBox3= rtBox1 | rtBox2; // 바른 결과 나옴
예2) CRect rtBox1(1, 1, 3, 3); CRect rtBox2(5, 5, 5, 5); // (5, 5, 5, 5) -> 정상적인 사각형이 아님(비사각영역) CRect rtBox3= rtBox1 | rtBox2; // rtBox3 에는 원하는 결과가 얻어지지않음
----------------------------- 6. 마치며 -----------------------------
이것으로 이번 강좌를 마칩니다.
지금까지의 내용을 정리해보면..
CRect 에 넣는 값은 "논리 좌표값" 이라고 생각해야 된다는 것이며
논리 좌표계에서는 "비사각영역"이 존재한다는 것입니다.
비사각영역으로 연산할경우 원하지 않던 결과가 도출된다는 현상도 말슴드렸구요..
제가 지금까지 글을 쓰면서 "픽셀 좌표계" 와 "논리적 좌표계" 라는 용어를 사용했습니다.
하지만 이것은 중요하지 않습니다.
physical coordinates / logical coordinates 라고 불릴수도 있고
픽셀 좌표계 / 픽셀 격자 외각 기준 좌표계라고도 불릴 수 있는 것입니다.
콩떡을 콩떡이라고 부르고 팥떡을 팥떡이라고 부르는데
왜 콩이 콩이고 팥이 팥이랍니까?.. 다 그냥 규약같은 겁니다.
음냥.. 쫌 무식한 예를 들긴 했지만..
아직 이부분에 다루시는 분도 못봤고, 이것에 대한 명확한 용어를 보지 못해서
최대한 의미를 살려서 "픽셀좌표계" "논리좌표계" 란 용어를 사용하였습니다.
원리를 이해하지 못하고 용어를 구사하는 것은 인생을 살아가는데 도움이 안됩니다.
기초적인 부분과 원리를 이해한다면 용어 자체는 문제될 것이 아니랍니당..
(하지만 기왕이면 모두가 쓰는 용어를 사용하는게 좋지요.)
그리고 이 강좌는 제가 데브피아 회원님들에게 도움드리려고 쓴 글이니
무단전재 하시거나 퍼가지 않으셨으면 해요...
지금까지 2회에 걸쳐서 이야기를 써봤는데.. 얼마나 잘 전달됐을지 모르겠네요.
정리한 내용은 쫌 더 있는데, 기회 봐서 담회 쓰던가 할께요..
왠지 마지막에 야리꾸리한 얘기로 끝내는거 같아서 찝찝하네용..
그럼 이만..
읽으시느라 수고하셨어요^^
마침.
|