티스토리 뷰

728x90
반응형

이전 포스팅에서 N차원까지 확장이 가능한 점의이동, 크기변환, 회전이동 기하변환에 대해서 다뤘습니다.

 

이때, N차원은 N개의 Element를 갖는 데카르트 좌표계를 사용했습니다.

 

기억하실지 모르겠지만, 기하변환에 사용되는 "동차 좌표"가 있다고 과거 포스팅에서 언급했습니다.

teus-kiwiee.tistory.com/42

 

1. 점과 선

컴퓨터의 화면은 점과 선 으로 이뤄져 있다고 할 수 있습니다. (결국 선도 점으로 이뤄져 있죠) 이때, 컴퓨터는 어떻게 점과 선을 표현할까요? 이번 포스트는 컴퓨터가 점과 선을 표현하는 방법

teus-kiwiee.tistory.com

3차원 좌표의 데카르트, 동차 좌표계 표기

지난번 포스트에서 3개의 기하변환을 다뤘고, 점의 이동은 Vector(Matrix)의 덧셈을 통해서 구했습니다.

데카르트 좌표계를 사용했을 경우, 2차원 좌표계의 기하 변환

 

이때 동차좌표계를 사용하면서 얻을 수 있는 장점은, 기하변환을 모두 행렬의 곱으로 표현이 가능하단 것 입니다.

동차좌표로 표현된 2차원 기하 변환

하나의 연산만으로 정리가 가능하면, GPU 같은 하드웨어의 설계를 오로지 Matrix 행렬곱을 구하는데 비중을 높이거나 

 

프로그래밍 코드가 훨신 간결해 질 수가 있습니다.

 

뿐만 아니라, 기본적인 3개의 기하변환 외 특수한 기하변환 모두 행렬곱으로 표현이 가능해집니다 :)

(특수한 기하변환은 다음시간에 다룹니다)

 

Python으로 구현한 기하변환 ver 동차좌표 입니다

import math
class geo_trans:
    def __init__(self, DT_list):
        #동차좌표를 적용하기 위해서 마지막에 1을 더해줍니다.
        self.data = DT_list + [1]
        
    #특별한 축을 입력하지 않을 경우
    #회전 평면은 [0,1] = [x,y]입니다.
    def oper(self, sort, degree, axis = [0,1]):
        #원본 좌표에 곱한 행렬을 구하기 위한 Frame을 준비합니다.
        mul_mat = [[0 for i in range(len(self.data))] for j in range(len(self.data))]            
        #원본 point와 동일한 Dimension을 갖는 Vector Frame을 준비합니다.
        temp_result = [0 for i in range(len(self.data))]
        #대각선 행렬을 1로 초기화해줍니다.
        i = 0
        while True:
            mul_mat[i][i] = 1
            i = i+1
            if i==len(mul_mat):
                break
        if sort == "move":
            #기존에는 move를 행렬의 덧셈으로 구했지만
            #이제는 동일하게 곱해줄 행렬을 구해줍니다.            
            for i in range(len(mul_mat)-1):
                mul_mat[i][len(mul_mat)-1] = degree[i]
        elif sort == "mag":            
            #크기변환 Mat을 만들기 위해서 대각선행렬에
            #크기변환 정도만큼의 값을 치환해줍니다.
            i = 0
            while True:
                mul_mat[i][i] = degree[i]
                i = i + 1
                if i==len(mul_mat)-1:
                    break                                         
        elif sort == "rot":                        
            degree = degree/180*math.pi
            #일반적인 2차원 좌표계의 Case(↑y+, →x+)
            if axis[0]<axis[1]:
                mul_mat[axis[0]][axis[0]] = math.cos(degree)
                mul_mat[axis[0]][axis[1]] = -math.sin(degree)
                mul_mat[axis[1]][axis[0]] = math.sin(degree)
                mul_mat[axis[1]][axis[1]] = math.cos(degree)
            #일반적인 2차원 좌표계에서 x가 reverse된 Case(↑y+, →x-)
            elif axis[0]>axis[1]:
                mul_mat[axis[1]][axis[1]] = math.cos(degree)
                mul_mat[axis[1]][axis[0]] = -math.sin(degree)
                mul_mat[axis[0]][axis[1]] = math.sin(degree)
                mul_mat[axis[0]][axis[0]] = math.cos(degree)
        #위 과정에서 결과물로 mul_mat만 구하고, 나머지는 행렬곱으로 동일합니다.
        #때문에 코드가 간결해집니다.
        #matrix 곱연산을 통해서 크기변환 결과를 구합니다.
        for i in range(len(mul_mat)):
            temp = 0
            for j in range(len(mul_mat)):                
                temp = temp + mul_mat[i][j]*self.data[j]                                
            temp_result[i] = temp
        return temp_result
        
import random
test_dt = [random.randint(1, 100) for i in range(10)]
#ex. [46,50,64,23,29,90,100,65,50,14]
#=> 요럴경우 동차좌표는 [45,50,64,23,29,90,100,65,50,14,1] 이 됩니다.
test = geo_trans(test_dt)

test.oper("move",[15,9,6,1,3,5,6,7,9,19])
Out[32]: [61, 59, 70, 24, 32, 95, 106, 71, 59, 33, 1]

test.oper("mag",[1,9,6,8,3,5,6,7,9,19])
Out[30]: [46, 450, 384, 184, 87, 450, 600, 448, 450, 266, 1]

test.oper("rot",145,[6,9])
Out[31]: [46, 50, 64, 23, 29, 90, -89.94527453781383, 64, 50, 45.889515015058706, 1]
728x90
반응형

'컴퓨터 그래픽스' 카테고리의 다른 글

6. 채색 알고리즘(수정중)  (0) 2021.02.15
5. 기하변환 3(복합기하변환, 아핀변환)  (0) 2021.02.13
3. 기하변환1(기본기하변환)  (0) 2021.02.11
2. 곡선과 원  (0) 2021.02.10
1. 점과 선  (0) 2021.02.09
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함