We are looking for a $4\times4$ transformation matrix for homogeneous coordinates which will map the viewing frustum, a truncated pyramid as described earlier, onto the standard cube in homogeneous coordinates $-1\le x'/w'\le +1, -1\le y'/w'\le +1, -1\le z'/w'\le +1$:

  • First, we consider the case of symmetrical perspective projection with $\theta_y = 90^\circ$ and r=1 (square window). The central projection (with center in the origin) of the viewing frustum on the plane z=-1 is then the square [-1,+1]2.

    This central projection is described by the following transformation matrix:

     \begin{displaymath}\mathbf{P} =
\begin{pmatrix}
1 & 0 & 0 & 0 \\
0 & 1 & 0 &...
...\end{pmatrix}
=
\begin{pmatrix}x \\ y \\ z \\ -z \end{pmatrix}\end{displaymath} (11)

    Indeed: the resulting point has affine coordinates $(\frac{x}{-z}, \frac{y}{-z}, -1)$, which is precisely the intersection of the line from the origin to the point (x,y,z) with the z=-1 plane.

    This transformation suffices when we are not interested in z'. This is the case when no visible face determination is needed.

  • The projection matrix P in (15) leaves the z-coordinate unchanged. After division by w'=-z we always obtain z''=-1. Due to the perspective division it is no longer possible to determine z'' as a linear function of z, as was the case in the third step of §5.1. However, it is still possible to construct the projection matrix such that $z'' = \frac {z'}{w'}$ is a monotonically increasing (non-linear) function of the depth -z of the point, in the range [-1,+1]. Fortunately, this is all we need for visible surface determination.

    z' is determined by the coefficients in the third row of P. We will now determine those coefficients so as to obtain the desired effect. The new matrix is designated by Q. There is no need for z' to depend on x or y. Therefore, the first two coefficients can have value 0. We will call the last two coefficients a and b. An arbitrary point (x,y,z,1), in eye coordinates, is then transformed into:

    \begin{displaymath}\begin{pmatrix}x' \\ y' \\ z' \\ w' \end{pmatrix} =
\mathbf{Q...
...d\Longrightarrow\quad
\frac{z'}{w'} = \frac{a\cdot z + b}{-z}.
\end{displaymath} (12)

    We want to map $z_{\text {front}}$ onto -1 and $z_{\text{back}}$ onto +1:
    $\displaystyle \frac{a\cdot z_{\text{front}}+ b}{-z_{\text{front}}}$ = -1  
    $\displaystyle \frac{a\cdot z_{\text{back}}+ b}{-z_{\text{back}}}$ = +1 (13)

    These two relations lead to a set of two equations with two unknowns a and b. Their solution is:
     
    a = $\displaystyle \frac{z_{\text{front}}+z_{\text{back}}}{z_{\text{front}}-z_{\text{back}}}$  
    b = $\displaystyle \frac{-2\cdot z_{\text{front}}\cdot z_{\text{back}}}{z_{\text{front}}-z_{\text{back}}}.$ (14)

    Figure 5 shows how $\frac{z'}{w'}$ varies as a monotonically increasing, but non-linear function of z.


      
    Figure: The graphs below show how the normalized device z-coordinate $z'' = \frac {z'}{w'}$ (vertical axis) varies as a non-linear, monotonically increasing function of -z, the distance from a point to the eye XY-plane (horizontal axis) when using the matrix Q. In the three cases shown, $z_{\text {back}}=-100$. The value of $z_{\text {front}}$ is -10, -1 and -0.1 in the left, middle and right graph respectively. Notice that the closer $z_{\text {front}}$ comes to the eyepoint z=0, the less uniformly the Z-buffer is filled: a larger range of eye z-values will be mapped onto a smaller range of Z-buffer values (values close to $\frac {z'}{w'} = +1$). When the Z-buffer has only a limited resolution (e.g. 16 bits), hidden face elimination with the Z-buffer algorithm will not work well for points in the far distance: points with large depth differences could then be represented by the same discrete Z-buffer value. This is why in practice, one should take care to position the front clipping plane $z=z_{\text {front}}$ as far as possible from the eye point.

  • The matrix Q suffices for symmetrical perspective projection with $\theta_y = 90^\circ$ and r=1. The general case should first be reduced to this special case. This step corresponds to the second step in §5.1

    • A symmetrical perspective projection with $\theta_y \ne 90^\circ$ and/or $r \ne 1$ is reduced to the previous case by simply scaling x and yby $\mathbf{M_s}(\vec{S})$ (2). The scaling factors are $\vec{S} = (\frac{2}{W}, \frac{2}{H}, 1)$ with W and H given in (11) (check this yourself!). The complete projection matrix for symmetrical perspective is then:
       \begin{displaymath}\mathbf{Q}\cdot\mathbf{M_s}(\vec{S}) =
\begin{pmatrix}
\frac...
...xt{front}}-z_{\text{back}}} \\
0 & 0 & -1 & 0
\end{pmatrix}.
\end{displaymath} (15)

    • For asymmetrical perspective projection the frustum is first transformed such that its axis coincides with the negative Z-axis. This requires a translation perpendicular to the Z-axis, over a distance proportional to -z (see figure 6). The top of the frustum lies in the origin and should remain there. The center $(\frac{x_{\text{right}}+x_{\text{left}}}{2}, \frac{y_{\text{top}}+y_{\text{bottom}}}{2}, z_{\text{front}})$of the front plane of the frustum should be mapped onto $(0,0,z_{\text{front}})$. This is called a shearing-transformation. The required transformation matrix is (check for yourself!):
      \begin{displaymath}\mathbf{S} =
\begin{pmatrix}
1 & 0 & \frac{x_{\text{right}}+...
...om}}}{-2z_{\text{front}}} \cdot z \\
z \\
1
\end{pmatrix}.
\end{displaymath} (16)

      The projection on the z=-1 plane is now symmetrical about the Z-axis, but its dimensions are not yet correct. The shearing transformation is therefore followed by a scaling transformation $\mathbf{M_s}(\vec{S})$(2) with
      \begin{displaymath}\vec{S} = \left(\frac{-2z_{\text{front}}}{x_{\text{right}}-x_...
...z_{\text{front}}}{y_{\text{top}}-y_{\text{bottom}}}, 1\right).
\end{displaymath} (17)

      $\mathbf{M_s}(\vec{S})$ reduces the dimensions $\frac{x_{\text{right}}-x_{\text{left}}}{-z_{\text{front}}}$ and $\frac{y_{\text{top}}-y_{\text{bottom}}}{-z_{\text{front}}}$ of the projection in the z=-1 plane to 2 units in the x and the y direction. The complete asymmetrical perspective projection matrix is:
       \begin{displaymath}\mathbf{Q}\cdot\mathbf{M_s}(\vec{S})\cdot\mathbf{S} =
\begin{...
...xt{front}}-z_{\text{back}}} \\
0 & 0 & -1 & 0
\end{pmatrix}.
\end{displaymath} (18)

      You should verify that this transformation, followed by a division by w', yields the same x'' and y'' as in §5.1. The z'' however is different, but still adequate for hidden face elimination.


  
Figure 6: An asymmetrical perspective projection reduces to a symmetrical perspective projection by a shearing transformation: a translation perpendicular to the Z-axis over a distance proportional to -z. This transformation maps the frustum axis on the negative Z-axis.

출처 : http://www.cs.kuleuven.ac.be/cwis/research/graphics/INFOTEC/viewing-in-3d/node8.html

혹시모르는 페이지 저장.. 

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

역행렬 구하기  (0) 2008.03.05
이중선형 필터링  (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

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

사용자 삽입 이미지

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

.. 자.. 저기서 파란색만 따로 어떻게 떼어낼까?
윈도에서 지원하는건... 학교에서 배운거는... 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
사용자 삽입 이미지
(원래 사진)
사용자 삽입 이미지

좀더 이해를 돕기 위해서
사용자 삽입 이미지
(원본)
사용자 삽입 이미지




아직 부족한건 많고 전진해야 한다. orz

소스와 원리는 http://rosagigantea.tistory.com/171 를 많이 참고

사용환경은 CImage를 사용해서 뿌렸기 때문에... ;; orz

게다가 단순 BackWard Mapping 방식이라 화상이 많이 쭈글거려진다... >_<

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

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
이미지 와핑에 관해서  (0) 2008.02.19
어디서 가져온건데.. 어디지;; orz

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

다각형을 가져오기 위한 노력...  (0) 2008.03.04
ImageWarping Processing  (0) 2008.02.26
PNG 분석자료들  (0) 2008.02.24
이미지 와핑 소스(그나마 낳은거)  (0) 2008.02.20
이미지 와핑에 관해서  (0) 2008.02.19
GDI+에서의 투명색 처리...  (0) 2008.01.25

+ Recent posts