티스토리 뷰
지난 포스팅에서 동차좌표계를 활용해서 기하변환을 모두 행렬의 곱으로 바꿨습니다.
이제, 이러한 기하변환은 여러번 취하는 복합기하변환에 대해서 알아봅니다.
1. 복합기하변환
한 점을 점의 이동 + 크기변환을 진행한다고 가정합니다.
지난번 포스팅에서 기하변환을 모두 행렬의 곱으로 나타냈기 때문에, 이 변환들 모두 행렬의 곱으로 표현됩니다.
그럼, P1-> P2로 가고, P2->P3로 갈 때 기하변환 Matrix끼리 곱해도 행렬의 형태가 유지되며
최종적으로 P1->P3로 이동한 결과를 얻을 수 있습니다!
(이때 행렬 곱의 순서는 바뀌면 안됩니다)
이러한 연산은 회전변환과 점의이동의 복합기하변환에서도 마찬가지입니다.
아래 예시를 보겠습니다.
위 경우 원점이 아닌 특정한 점(x1, y1)을 기준으로 회전할려고 합니다.
이때 기존에 기술한 회전변환을 적용할 경우, (0,0)을 기준으로 회전변환이 되어 원하는 것과 다른 결과를 얻게됩니다.
이때, 복합 기하변환은 적용하면 쉽게 결과를 얻을 수 있습니다.
위처럼 점의이동 -> 회전변환 -> 점의이동을 순서대로 행렬곱을 적용해 주면 됩니다.
이러한 논리는 3차원에 적용해도 정상적으로 작동하는것을 식을 통해서도 알 수 있습니다 :)
2. 아핀변환
아핀변환은 회전과 이동변환이 혼합된 혼합기하변환 중 특별한 변환을 의미합니다.
아핀변환의 특징을 뽑자면
1. 동일 직선에 있던 3개의 점은 변환 후에도 동일한 직선 위에 존재
2. 3개의 점이 같은 선 위에 있을때, 선간의 길이의 비는 변환 후에도 동일
3. 평한한 선들을 변환 후에도 평행성 유지
변환 전-후를 살펴보면, 원점이 bx, by만큼 이동한 상태에서 기존의 x,y 축이 찌부된 것 과 같은 모습을 보입니다.
아핀변환행렬에서 (axx,axy,ayx,ayy)는 도형의 단위벡터(기본은 X,Y축이라고 할 수 있습니다)를 회전시키는 역할을 하고
(bx,by)는 회전과 동시에 점들의 이동에 관여하는 성분입니다.
즉, 크기변환 없이 회전 변환과 점의 이동이만 일어나는 기하변환 입니다.
이때 bx,by가 0일 경우 원점에서 단위벡터의 방향만 변하게 됩니다.
이점을 이용하면, 새로운 좌표계를 기준으로 변환을 하는것이 가능해집니다!
보시는것처럼, 아핀변환의 회전 성분은 원점을 기준으로한 회전변환 입니다.
이때, 이 회전변환 행렬을 값으로 산출하면 변환 후 회전된 축의 단위벡터를 구할 수 있게됩니다:)
Python으로 구현해본 아핀변환 입니다 :)
import copy
class affine:
def __init__(self, DT_list):
#입력받은 데이터를 가지고 동차좌표로 변환해줍니다.
for i in range(len(DT_list)):
DT_list[i] = DT_list[i] + [1]
self.data = DT_list
#변환된 Point를 저장할 List를 생성합니다.
self.trans_data = copy.deepcopy(self.data)
def trans(self, rot_comp=1, b_comp=1):
#아핀변환을 위한 아핀행렬을 만들 Frame을 미리 만들어줍니다.
af_mat = [[0 for i in range(len(self.data[0]))] for i in range(len(self.data[0]))]
#회전성분이 없으면 0으로
#회전성분이 있으면 해당 값으로 치환해줍니다.
#이때 회전성분의 input은 [[x1,y1,z1],[x2,y2,z2]....]입니다.
if rot_comp == 1:
pass
else:
for i in range(len(rot_comp[0])):
for j in range(len(rot_comp)):
af_mat[j][i] = rot_comp[i][j]
#이제 회전+이동성분이 없으면 0
if rb==1 or rb==[0,0] or rb == [0,0,0]:
pass
#있으면 이동성분의 값을 아핀행렬에 삽입합니다.
else:
for i in range(len(b_comp)):
af_mat[i][len(b_comp)] = b_comp[i]
#이제 입력된 점과 아핀행렬을 행렬곱을 하여
#아핀행렬 후 변환된 점의 위치를 구합니다.
for k in range(len(self.data)):
temp2 = []
for i in range(len(self.data[0])):
temp = 0
for j in range(len(self.data[0])):
temp = temp + af_mat[i][j]*self.data[k][j]
temp2 = temp2 + [temp]
self.trans_data[k] = temp2
#동차좌표를 데카르트 좌표로 바꿔주기 위해서 마지막 1값을 제거합니다.
for i,j in zip(self.trans_data,self.data):
i.pop()
j.pop()
import random
data = [[random.randint(10,20) for i in range(2)] for i in range(10)]
test = affine(data)
#아핀행렬의 회전성분 입력
rot = [[1,1],[-1,1]]
#아핀행렬의 회전&이동성분 입력
rb = [0,0]
test.trans(rot, rb)
af_data = test.trans_data
#아핀행렬 변환 전<->후 시각화
import matplotlib.pyplot as plt
plt.figure(figsize = [5,5])
plt.scatter([data[i][0] for i in range(len(data))] ,[data[i][1] for i in range(len(data))])
plt.scatter([af_data[i][0] for i in range(len(af_data))] ,[af_data[i][1] for i in range(len(af_data))])
plt.scatter(0,0)
'컴퓨터 그래픽스' 카테고리의 다른 글
7. Color의 표현 (0) | 2021.02.16 |
---|---|
6. 채색 알고리즘(수정중) (0) | 2021.02.15 |
4. 기하변환2(동차좌표ver) (0) | 2021.02.12 |
3. 기하변환1(기본기하변환) (0) | 2021.02.11 |
2. 곡선과 원 (0) | 2021.02.10 |
- Total
- Today
- Yesterday
- AVX
- 사칙연산
- 분할정복
- 동적계획법
- 알고리즘
- 이분탐색
- git
- SIMD
- 완전탐색 알고리즘
- Python
- 컴퓨터그래픽스
- heap
- 병렬처리
- prime number
- GDC
- Greedy알고리즘
- 프로그래머스
- 코딩테스트
- C++
- Sort알고리즘
- hash
- Search알고리즘
- 자료구조
- stack
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |