그동안 나의 삽질을 소개합니다..
아래아래아래 포스트에 보면.. 이미지 와핑에 관해 있는데..
여러 조각을 잘라서 따로 와핑을 해줄려고 하는데 사각형 문제가 일어난다.

사용자 삽입 이미지

검은 사각형 테투리가 와핑 영역이고
빨간 사각형 영역이 때어내올 이미지 영역이며
파란 브러쉬 부분이 실제 와핑 영역이다...

.. 자.. 저기서 파란색만 따로 어떻게 떼어낼까?
윈도에서 지원하는건... 학교에서 배운거는... CRect 같은 사각형 영역이나 원 영역..(이건 아니니 패스)..
그래서.....

여러가지 짓을 한결과 공통수학시간때 배운..... 직선의 방정식이 생각났다..
그래서.. 직선의 방정식 & 부등식에 관한 소스를 만들었다

// 두점이 이루는 직선방정식에서, 점 x,y가 그래프상 위인지 아래인지 알려주는 함수
float LineAnInequality(CPoint LinePos1, CPoint LinePos2, int x, int y, float &tilt)
{
 if((LinePos2.x - LinePos1.x) == 0)
 { // 분모가 0이면..  즉, x = a 꼴의 수평의 직선이 된다.
  tilt = 0;
  if(LinePos2.x == x)
   return true;
  else
   return false;
 }
 else if((LinePos2.y - LinePos1.y) == 0)
 { // 분자가 0이면..  즉, y = a 꼴의 수직의 직선처리
  tilt = 0;
  if(LinePos2.y >= y)
   return true;
  else
   return false;
 }
 // 기울기 구한다.
 tilt = (float)(LinePos2.y - LinePos1.y) /  (float)(LinePos2.x - LinePos1.x)  ;

 // 참고로 기울기 관해서..
 // 위의 기울기 구하는 함수를 쓸려고 했더니 수직, 수평에서 문제가 발생.. orz
 // 귀찮으므로 그냥 쓴다. 자바로 변환시 좀 생각해볼 문제..

 // 기울기의 크기를 측정해서
 float tmp = abs(tilt);
 
 bool flag;
 // 기울기가 1이하이면 y에 대해 값을찍고
 if(tmp <= 1)
 {
  if((int)y >= (int)((tilt  *  (float)(x - LinePos1.x) + LinePos1.y)))
   flag = true;
  else
   flag = false;
 }
 // 기울기가 1이상이면 x에 대해 값을 찍어야 선이 재대로 찍힌다.
 if(tmp > 1)
 {
  if((int)x <= (int)((y-LinePos1.y)/tilt + LinePos1.x))
   flag = true;
  else
   flag = false;
 }
 
 return flag;
}

점 2개로 이루어진 직선 방정식에서, x,y 위치가 직선방정식의 위(true)인지 아래(false)인지 판단한다.
옆에 tilt 는.. 기울기 값을 참고하기 위해 가져왔다.
참고로 위의 함수는... 부등호를 = 으로 고치기만 하면 직선 방정식에 대한 그래프를 그릴수도 있다.

이걸 써서..
bool IsRectIn(CPoint TopLeft, CPoint TopRight, CPoint DonwLeft, CPoint DownRight, int x, int y)
{

 // 직선의 부등식을 사용해서 만든 사각형 면체우기 알고리즘
 // 이부분 개선해야 함.. orz
 bool flag = false; // 결과 플레그
 float tilt;   // 기울기 수치

 // 두점의 직선 부등식을 사용. 은근슬적 기울기를 가져온다.
 flag = LineAnInequality(TopLeft, TopRight, x, y, tilt);
 if(tilt == 0)// || tilt > 1.5)
  flag = !flag;
 
 if(flag)
 {
  flag = !LineAnInequality(TopLeft, DonwLeft, x, y, tilt);
 // if(tilt >= 0)
 //  flag = !flag;
 
  if(flag)
  {
   flag = LineAnInequality(DonwLeft,DownRight, x, y, tilt);
   if(tilt != 0)// || tilt >= 1.0f)
    flag = !flag;
   
   if(flag)
   {
    if(LineAnInequality(DownRight,TopRight, x, y, tilt))
    {
     // 이 4개의 직선부등식 안에 들어와야 true를 받는다 ㅡㅡ...
     // 이게 때에 따라 좀 바뀌는듯.. 어찌 해야 하남 ㅡ_ㅡ..
     flag = true;
    }
    else
     flag = false;
   }
  }
 
 }
 return flag;
}

이런식으로 활용하면, 사각형을 왠만하면 끄집어낼수 있었다...
허나... 아랫변.... 과 윗변... 이것이 기울기가 1이 넘어가면 문제가 생기는 현상이 일어났다
게다가.. 이 프로젝트 자체가 위피라는 아주 열악한 곳에서 돌아가야 하기때문에
1픽셀에 4개의 방정식 연산 하는건... 단순히 생각해도 좋지 않다.. (지못미 CPU...)

그러다가... 기초로 돌아갔다..
CRgn.... 대부분 skip으로 넘어가는 구조체..
이녀석의 역활은 점으로 이루어진 영역을 가져온다.

그래서 이녀석을 좀 활용해 봤는데..

사용자 삽입 이미지






























노란색이 이미지 설정 지역이다.. 파란색은 스킵 지역..

....
뭐가 문제일까 보다가..
CRgn 영역을 지정한 포인터 영역을 이리저리 돌려봤다.

ㅡㅡ..

제길.. orz 이거.. 반시계 방향으로 포인터를 지정해야 했었다.

아래는 영역을 가져오기 위한 처절한 소스이다..

CPoint pt[4];
// 사각형이 반시계 방향..
 pt[0] = m_NewMesh[drawX][drawY]   -  m_NewMesh[drawX][drawY];
 pt[3] = m_NewMesh[drawX+1][drawY]  -  m_NewMesh[drawX][drawY];
 pt[1] = m_NewMesh[drawX][drawY+1]  -  m_NewMesh[drawX][drawY];
 pt[2] = m_NewMesh[drawX+1][drawY+1]  -  m_NewMesh[drawX][drawY];
 
 CRgn rgn;
 rgn.CreatePolygonRgn(pt, 4, ALTERNATE);    // pt 4점으로 이루어진 영역 설정
 
 //rgn.Detach();
 for(int x=0; x<dw;x++)
 {
  for(int y=0; y<dh; y++)
  {
   if(rgn.PtInRegion(x,y))   // 영역안?
    RectImage->SetPixel(x,y,RGB(0xff,0xff,0));
   else
    RectImage->SetPixel(x,y,RGB(0,0,0xff));
  }
 }
// 참고로  CImage 에서 GetDC를 쓸땐.. HDC hdc로 빼서 쓴뒤
// 이걸 변수를 매개체로 사용해야 하고
// 나중에 꼭 ReleaseDC() 를 해줘야 함..

// CBrush  hBrush(COLORREF(RGB(0xff,0,0xff)));
// HDC hdc = RectImage->GetDC();
// SelectObject(hdc, hBrush);
 
// Polygon(hdc, pt, 4);  // API 함수.. 이런식으로 응용 가능.

 //RectImage->MaskBlt(m_ScrImage->GetDC(),pt);
//RectImage->ReleaseDC();

'알고리즘 > 이미지 처리' 카테고리의 다른 글

이중선형 필터링  (0) 2008.03.05
Perspective projection matrix  (0) 2008.03.05
다각형을 가져오기 위한 노력...  (0) 2008.03.04
ImageWarping Processing  (0) 2008.02.26
PNG 분석자료들  (0) 2008.02.24
이미지 와핑 소스(그나마 낳은거)  (0) 2008.02.20

+ Recent posts