Review2010. 9. 11. 20:55




근래에 사적인 일이 너무 많아 아꿈사 스터디에 많이 빠졌었고,
얼마 전까지는 참석은 해도 제대로 집중을 못 했었었다.

스스로 공부하지 않고 발표 내용만을 들었기 때문에 하루만 지나면 머리 속에 남는 것이 없었다... ㅜㅜ
너무 진도가 빨라서 그런가? 안하는 버릇하다가 다시 하는 버릇 들이기 힘들어서 그런가? 하는 중에 ...
이번 스터디에서 '프로그래머의 길. 멘토에게 배워라'라는 책을 스터디 하게 되었는데,
나로 하여금 학습의 의지를 다시 불끈불끈하게 고취시켜주었다. ^^;


이 책에 대해선
수명님 블로그에서 리뷰를 읽고,
'패턴이라고? 이거 꼭 봐야겠는데?' 라며 찜리스트에 담아뒀던 녀석이었다.
이 책은 우리가 마주치고 고민하는 여러 상황들을 패턴화해서,
이 상황을 정의하고 극복하는 방법을 제시해 주는 식으로 구성되어있다.


가슴에 와 닿았던 챕터들로는... 요런 것들이었다.

크든 작든 자신에게 동기 부여를 계속 해서 수련에 끊임이 없도록 하라는 지속적인 동기 부여,
긍적적인 아이디어로 대화를 나누고 개선에 대해 노력하고 회고하며 좋아하는 일을 하라는 열정을 키워라,
논리적+의욕적으로 경력의 다음 단계를 스스로 준비하고 확장해 나가라는 자신만의 지도를 그려라,
아무리 좋은 제안이 오더라도 야전의 참호 안에 머물러라는 전장에 머물러라,
개발의 조직 문화가 당신을 낙담시킨다면 오프라인 모임에 참가하라는 마음 맞는 사람들,
생산성은 그럭저럭이지만 학습은 제자리라면...뭔가 수준 높은 테크닉을 배워야 하므로 팔꿈치를 맞대고,
어디서든지 책을 읽음에 끊김이 없도록 항상 책을 지녀라 꾸준히 읽어라,
수명이 긴 책을 도서 목록에 추가하고 유명했던 기사를 찾아 읽어라는 고전을 공부 하라,
피상적으로 알아봤자 도움이 안된다. 무지를 파악해라는 더 깊이 파고 들어라


책의 내용도 좋았지만 스티디 내용에 대해 토론했던 시간이 정말 값진 시간이었다.

책에 정의된 패턴에 대해서 회고 하는 식의 토론이었는데, 곱씹어 생각하고 실천해야 할 내용들이었다.

 - 스펙을 등한시 하고 대충 맞겠거니... 하고 작업했던 일이 엄청나게 큰 손실을 가져왔다.
 - 가족과의 시간이 너무 소중하기 때문에 일이나 자기 개발을 위해 새벽에 2시간을 할애 한다.
 - 소장의 가치를 검증하기 어려운 책은 공공 도서관이나 회사 도서관을 이용해라.
 - 무지를 드러낼 줄 알아야 하고, 자신을 낮출줄 알아야 한다.
 - 소위 '성공한 사람'이라고 불릴만한 유명한 사람의 인터뷰나 기고글을 찾아 읽어라.
 - 관리자와 개발자의 관계가 수평적인 관계가 되어야 한다.
 - 목표를 정하되 난이도를 정의해서 끊임없이 피드백 받도록 하자.
 - 책을 읽고 마인드 맵을 정리해보자.


책의 패턴 중에 배운 것을 기록하고 공유하라는 내용도 있고,
스터디에 나오시는 여러 분들을 본 받아 보려는 취지에서 스터디에서 오늘 막 끝낸 책의 내용에 대해 정리해 보았다.
처음 작성하는 리뷰라서 그런지 꽤 시간이 많이 걸렸음에도 불구하고 많이 부족한 글이긴 하다.
하지만 꾸준히 연습, 연습, 또 연습하면 작성하는 글의 속도와 질이 올라가리라 믿고 첫 리뷰를 마친다. 



P.S.
- 내가 1년 전만 이라도 이 책을 봤으면 참 좋았을 텐데...
- 뉴타입이 아닌 일반 신입이 이 책을 보고 유레카를 외칠 수 있을까?
   ...하는 의문이 들지만 그래도 읽어 보라고 추천할만 함. 나중에 꺼내 보면 되니까ㅎ : )

'Review' 카테고리의 다른 글

Visual Studio 2010 겨울밤 세미나 - 첫번째 밤  (0) 2010.12.03
G-Star 후기  (0) 2010.11.23
Posted by codevania
Code Snippets/Boost2010. 9. 9. 16:20

boost::bind를 사용하면 많은 양의 중복 코드를 제거할 수 있다.
하지만 과유불급!!
좋다고 너무 남발하면 코드는 복잡해져서, 읽고 이해하고 유지보수 하기 어렵게 된다.
잘난척 남발하며 쓰다간 결국 동료들에게 대단히 민폐를 끼치는 것이 된다. (모든 사람이 boost를 사랑하진 않는다)
일단 이번에는 간단히 중첩 bind 사용에 대해서만 보이도록 하고,
다음에 지나치게 복잡해서 지양 해야할 bind 사용에 대해 알아보자.

Posted by codevania
Graphics2010. 9. 7. 10:11

 

 

Normal Transforms

By Eric Haines (erich@acm.org)  and Tomas Möller (tompa@acm.org)

 

Normal이 어떻게 Transform되는가?

geometric object를 transform하는 행렬이 object의 normal을 변경할 수 있다.

그러나, 그 상황이 아닌 경우를 이해해야한다.

부적절한 transforming normals는 잘못된 culling과 linghting 결과를 유발한다.

incoming geometry를 잘 다루기 위해서는 transforms의 타입을 잘 알아야한다.

 

Normal은 반드시 역행렬의 전치행렬에 의해서 transform되야한다.

geometry를 transform하는 행렬을 M이라고하면, 이 geometry의 normal을 transform하기 위한 N은 아래의 것을 사용해야한다.

  1.                N = transpose( inverse(M) )

 

 

전치행렬은 대각 축을 따라서 뒤집은 형태다. 왼쪽이 주어진 행렬, 오른쪽이 전치행렬이다.

M = \begin{vmatrix} a & b & c \ d & e & f \ g & h & i \end{vmatrix}           M^{T} = \begin{vmatrix} a & d & g \ b & e & h \ c & f & i \end{vmatrix}


Figure 1 shows what can happen if the proper transform is not used.

[링크 깨짐. 직접 제작 필요]

 

  • 좌: original geometry
  • 중: 모델이 x축으로 0.5 scl되었고, normal이 이 scl 행렬을 사용했을 때
  • 우: 제대로된 normal 변형.

 

실제로, 행렬이 orthogonal임을 알면 inverse를 구할 필요가 없다. (i.e. 회전으로만 구성되어 있었다... ..; )

여기서는, original 행렬은 normals를 transform 가능하다. ortho행렬의 역행렬이 그것의 전치행렬이기때문이다.

Two matrix transposes cancel out, giving the original rotation matrix.

게다가, translation은 direction에 영향을 미치지 않기 때문에 몇 번이나 해도 상관없다.

transformation후에 normals의 renormalizing의 단계(크기를 1로 만드는 것)를 피할 수 있다.

회전&이동만 있는 행렬(rigid-body transforms)에 의해서는 길이는 보존되기 때문이다.

 

최종적으로, uniform scl을 가진 회전&이동으로 구성된 행렬이 사용되었다면, 

그런 scl은 transformed normal의 길이에만 영향을 주지 방향에는 영향을 주지 않는다.

uniform scl은 object의 크기를 동일하게 증감 시킨다. ( D3DXMatrixScaling( n, n, n )으로 만들어진 행렬 같은 것 )

non-uniform scl은 object를 stretch or squeeze할 수 있다. (i.e. xyz구분 없이 막 늘렸다 줄였다 할 수 있다)

uniform scl이 사용되면 normals는 renormalize 될 필요없다.

요약하면, Uniform Scl & Rotation & Translatoin으로 구성된 행렬로 object가 변환되면, normal은 안전하게 변환된다.

 

full inverse가 계산되었다고 할지라도, 행렬 좌우측 3x3의 adjoint(수반행렬)의 전치행렬만 요구된다.

수반행렬은 (계산된 행렬이 original 행렬의 행렬식으로 나누지 않는다는 것을 제외하고는) 역행렬과 비슷하다.

수반행렬은 역행렬을 구하는 것 보다 빠르다.

변환된 normal을 구하기만 하면 되므로 행렬식으로 나눌 필요가 없다.


표면 노말 변형을 삼각형으로 부터 구하는(e.g. 삼각형의 edges의 외적을 사용하는) 시스템에서는 문제가 되지 않는다.

그러나, 삼각형 정점들이 lighting을 위해 normal 정보를 가지고 있는 경우가 흔하기 때문에 normal transformation은 언급되어야만 한다.

 

 

부록: adjoint 계산. 3x3 행렬의 adjoint의 전치를 구하는 코드 제공.
  1.  
    typedef struct ModelMatrix {    
        float mtx[3][3];       // rotation/scale/shear matrix    
        float translate[3];    // translation
    } ModelMatrix;

    transpose_adjoint( ModelMatrix *m, ModelMatrix *adjoint )
    {
       
        // cofactor for each element
        adjoint->mtx[0][0] = m->mtx[1][1] * m->mtx[2][2] - m->mtx[1][2] * m->mtx[2][1] ;    
        adjoint->mtx[0][1] = m->mtx[1][2] * m->mtx[2][0] - m->mtx[1][0] * m->mtx[2][2] ;    
        adjoint->mtx[0][2] = m->mtx[1][0] * m->mtx[2][1] - m->mtx[1][1] * m->mtx[2][0] ;    
        adjoint->mtx[1][0] = m->mtx[2][1] * m->mtx[0][2] - m->mtx[2][2] * m->mtx[0][1] ;    
        adjoint->mtx[1][1] = m->mtx[2][2] * m->mtx[0][0] - m->mtx[2][0] * m->mtx[0][2] ;    
        adjoint->mtx[1][2] = m->mtx[2][0] * m->mtx[0][1] - m->mtx[2][1] * m->mtx[0][0] ;    
        adjoint->mtx[2][0] = m->mtx[0][1] * m->mtx[1][2] - m->mtx[0][2] * m->mtx[1][1] ;    
        adjoint->mtx[2][1] = m->mtx[0][2] * m->mtx[1][0] - m->mtx[0][0] * m->mtx[1][2] ;    
        adjoint->mtx[2][2] = m->mtx[0][0] * m->mtx[1][1] - m->mtx[0][1] * m->mtx[1][0] ;
    }

 

 

References

  1. Hanrahan, Pat, "A Survey of Ray-Surface Intersection Algorithms", chapter 3 in Andrew Glassner (editor), An Introduction to Ray Tracing, Academic Press Inc., London, 1989.
  2. Turkowski, Ken, "Properties of Surface-Normal Transformations", in Andrew Glassner (editor), Graphics Gems, Academic Press, Inc., pp. 539-547, 1990. http://www.worldserver.com/turk/computergraphics/index.html

 

 

내용 제대로 알지도 못하고 있다가, 면접가서 멍소리를 한 쓰라린 기억이... ㅜㅜㅎ

 

이 글은 스프링노트에서 작성되었습니다.

'Graphics' 카테고리의 다른 글

Normal vector compression  (0) 2011.07.11
Posted by codevania