Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[13728] Re:Re:이미지 회전 및 변환에 대해 문의드립니다
문의드립니다 [] 2179 읽음    2011-06-08 14:49
답변달아주셔서 감사합니다...
근데 위의 프로젝트인 경우 가로길이를 증가시킬 경우 왼쪽 오른쪽이 같은 크기로 증가되네요...

혹시 왼쪽 또는 오른쪽 한 방향으로 증가시킬 수 있는 방법은 없나요??ㅠㅜ


오랑캐꽃 님이 쓰신 글 :
: 문의드립니다 님이 쓰신 글 :
: : 안녕하세요
: :
: : 이미지를 회전 시킨 후에 크기를 변경 시키는 작업을 하려고 합니다..
: :
: : 회전 알고리즘은
: : 이미지의 중심점 point와 회전을 시작하는  point 값을 이용해서 구했는데요..
: :
: : 회전한 후에 크기 변경을 시켜주려면 어떤 계산식을 써야하는건가요??
: :
: : 단순하게 회전 시킨 이미지를 원위치로 옮긴 후 이때 증가된 넓이 또는 높이 값을 저장한 뒤에
: : 다시 회전을 시켜줬더니 이미지 크기 변경 전과 변경 후 회전 시 사용되는 중심점의 위치가 달라지다보니
: : 출력되는 위치가 사이즈 변경 전 후과 다르네요...
: :
: : 님들 조언 꼭 좀 부탁드립니다..
:
:
:
: 공돌이의 친구 행렬을 쓰시면 생각이 단순해집니다.
:
: 임의의 도형을 이루는 점 P를 점 C를 중심으로 th만큼 회전하고 S만큼 크기변환 하려면
: 다음 과정을 거치면 됩니다.
:
: 1. 중점 C가 원점이 되도록 이동변환.
: 2. S 만큼 크기변환.
: 3. th 만큼 회전변환.
: 4. 다시 C 만큼 이동변환.
:
: 각 단계에 필요한 2차원 동차행렬은 다음과 같습니다.
:
: 1.
:
: T1 =
:
: 1, 0, 0
: 0, 1, 0
: -Cx, -Cy, 0
:
:
: 2.
:
: S1 =
:
: Sx, 0, 0
: 0, Sy, 0
: 0, 0, 1
:
:
: 3.
:
: R1 =
:
: cos(th), sin(th), 0
: -sin(th), cos(th), 0
: 0, 0, 1
:
:
: 4.
:
: T2 =
:
: 1, 0, 0
: 0, 1, 0
: Cx, Cy, 0
:
:
: 변환된 점 P' = P * T1 * S1 * R1 * T2 가 됩니다.
: 행렬에는 교환법칙이 성립하므로 행렬끼리만 곱해준 M 을 구해주면 대략 다음과 같지요.
:
: M =
:
: Sx * cos(th), Sy * sin(th), 0
: - Sy * sin(th), Sy * cos(th), 0
: - Sx * Cx * cos(th) + Sx * Cy * sin(th) + Cx, - Sy * Cx * sin(th) - Sy * Cy * cos(th) + Cy, 1
:
:
: 여기에 점 P를 곱해 풀어주면
:
: Px' = Px * Sx * cos(th) - Py * Sy * sin(th) - Cx * Sx * cos(th) + Cy * Sy * sin(th) + Cx
: Py' = Px * Sx * sin(th) + Py * Sy * cos(th) - Cx * Sx * sin(th) - Cy * Sy * cos(th) + Cy
:
:
: 좀 보기 좋게 정리하면
:
: Px' = cos(th) * (Px * Sx - Cx * Sx) - sin(th) * (Py * Sy - Cy * Sy) + Cx
: Py' = cos(th) * (Py * Sy - Cy * Sy) + sin(th) * (Px * Sx - Cx * Sx) + Cy
:
: 그게 그건가...
:
: 아무튼 이제 이 식에 따라 P 를 P' 에 옮겨 찍어주면 됩니다만... 스케일이 커진다면 듬성듬성
: 비는 곳이  생기겠지요. 때문에 실제로는 새로 준비된 버퍼, 즉 P'에 따른 원래 P의 위치를 계산하는
: 방식이 되어야 하고, 따라서 대상 점의 입장에서 지금까지 계산의 역변환을 적용해주어야 합니다.
:
: 위에서 계산한 행렬 M의 역행렬을 InvM 라고 하면
:
: P = P' * InvM
:
: 가 되지요. 그런데 변환행렬의 은 그 특성상
:
: InvM = InvT2 * InvR1 * InvS1 * InvT1
:
: 과 같습니다. 이미 각 단계의 변환값을 알고 있기 때문에 굳이 역행렬을 구하느라 CPU를
: 낭비할 필요 없이 이전 행렬의 값을 바꿔서 4->3->2->1 순으로 곱해주기만 하면 되지요.
: 회전값은 음수로, 스케일값은 역수로, 이동값은 반대로... 다음과 같이요.
:
: th = -th,
: Sx = 1/Sx
: Sy = 1/Sy
:
:
: 각 단계의 역변환 행렬을 뒤에서부터 곱해준 결과는 다음과 같습니다.
:
: cos(th) * Sx, sin(th) * Sy, 0
: - sin(th) * Sx, cos(th) * Sy, 0
: - (Cx * cos(th) - Cy * sin(th)) * Sx + Cx, - (Cx * sin(th) + Cy * cos(th)) * Sy + Cy, 1
:
:
:
: P'를 대입해 풀어주면
:
: Px = cos(th) * Sx * Px' - sin(th) * Sx * Py' - (Cx * cos(th) - Cy * sin(th)) * Sx + Cx
: Py = sin(th) * Sy * Px' + cos(th) * Sy * Py' - (Cx * sin(th) + Cy * cos(th)) * Sy + Cy
:
:
: 이제 이 식에 맞추어 점을 찍어주면 됩니다.
:
: 오래간만에 행렬을 풀어보니 머리에 쥐가나네요.
: 풀이가 제대로 되었는지 확인해 볼 겸 간단한 예제를 만들어 첨부했습니다.
: Canvas의 Pixels 프로퍼티를 직접 건드리기 때문에 속도는 안습이고요...
: 스케일시 필터링도 적용하지 않았습니다. 어차피 이 부분이 주가 아니기 때문에... ^^;

+ -

관련 글 리스트
13724 이미지 회전 및 변환에 대해 문의드립니다 문의드립니다 2597 2011/06/07
13727     Re:이미지 회전 및 변환에 대해 문의드립니다 오랑캐꽃 2574 2011/06/08
13728         Re:Re:이미지 회전 및 변환에 대해 문의드립니다 문의드립니다 2179 2011/06/08
13729             Re:Re:Re:기준위치, 그러니까 중점을 적당히 바꿔보세요. 오랑캐꽃 1721 2011/06/08
13730                 Re:Re:Re:Re:기준위치, 그러니까 중점을 적당히 바꿔보세요. 문의드립니다 1855 2011/06/08
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.