티스토리 뷰

컴퓨터 그래픽스

8. 2차원 뷰잉

Teus 2021. 2. 17. 08:00
728x90
반응형

지난번 포스팅까지 해서 어떻게 선을 그리는지, 어떻게 색을 구성, 채우는지 확인하였습니다.

 

이번 포스팅은 이렇게 결정된 도형을 2차원 화면에 Rendering 할 영역을 설정하는 내용입니다.

 

아래 예시를 보시죠

 

두가지 도형의 Rendering 영역(빨간 사각형)

파란색 삼각형과 초록색 원 모두 계산완료 하였지만, 실제 화면에 보여질 영역은 빨간 사각형 입니다.

 

이런 빨간영역 만 남길때, 기존에 포스팅했던 기하변환을 사용합니다.

 

특정 영역을 클리핑 후 정규화 하는 과정

보시는것 처럼, 크기변환 과 점의이동 두가지 기하변환을 순서대로 적용합니다.

 

1. (X_min, Y_min)을 기준으로 Size를 크기를 2로 바꾸는 크기변환 행렬을 구한다.

└1_1. 1을 진행하기 위해서 (X_min, Y_min)을 (0, 0)으로 이동시킨다.

2. (X_min, Y_min)을 (-1,-1) 로 이동시키는 점의 이동 행렬을 구한다.

3. 크기변환 -> 점의이동 순으로 동차좌표계에 행렬의 곱을 적용한다.

 

이런 기하변환을 위한 Ms(크기변환), Mt(점의이동) 행렬은 다음과 같이 구할수있습니다.

2차원 뷰잉 클리핑을 위한 기하변환

 

이렇게 -1~1사이의 좌표로 특정 부분을 클리핑 한 것을 정규화된 좌표계라고 합니다.

 

이제 해당 클리핑된 부분만 화면에 보여주면 되겠죠 :)

 

Python으로 구현한 Clipping 소스코드입니다.

class clipping:
    #x_range = [x_min, x_max], y_range = [y_min, y_max]
    #과 같은 형식으로 받아서 Clipping Class를 만들어줍니다.
    def __init__(self, x_range, y_range):
        self.x_min = x_range[0]
        self.x_max = x_range[1]
        self.y_min = y_range[0]
        self.y_max = y_range[1]
        self.first_mat = [[1,0,-self.x_min],
                          [0,1,-self.y_min],
                          [0,0,          1]]
        self.second_mat =[[2/(self.x_max-self.x_min),0,0],
                          [0,2/(self.y_max-self.y_min),0],
                          [0,0,                        1]]
        self.third_mat = [[1,0,-1],
                          [0,1,-1],
                          [0,0, 1]]
    
    #행렬곱을 연산할 매쏘드를 만들어줍니다.
    def mat_mul(self, mat,pt):
        result = []        
        for i in range(len(mat)):
            temp = 0
            for j in range(len(mat)):
                temp = temp + mat[i][j]*pt[j]
            result = result + [temp]
        return result
        
    #point를 받아서 기하변환을 할 메쏘드를 만듭니다
    #여기서 Point로 2차원 점[x,y]형식으로 입력합니다.
    def cal(self, point):
        #일반 데카르트 좌표를 받아서 동차좌표로 변환합니다.
        point = point + [1]        
        #x_min, y_min을 원점으로 이동시키는 이동변환
        trans_pt = self.mat_mul(self.first_mat, point)
        #x_range와 y_range를 2로 크기를 바꾸는 크기변환
        trans_pt = self.mat_mul(self.second_mat, trans_pt)
        #x_min, y_min을 -1,-1로 이동시키는 이동변환
        trans_pt = self.mat_mul(self.third_mat, trans_pt)
        #변환된 동차좌표를 
        trans_pt.pop()
        return trans_pt
        
        
        

clipping_wnd = [[5,20],[10,20]]                
test= clipping(clipping_wnd[0],clipping_wnd[1])
import random
data = [[random.randint(5,25),random.randint(5,30)] for i in range(50)]
trans_data = []
for i in range(len(data)):
    trans_data = trans_data + [test.cal(data[i])]

#변환 전 Point와 클리핑 window를 확인합니다.
import matplotlib.pyplot as plt
plt.figure(figsize = [5,5])
plt.xlim(0,33)
plt.ylim(0,33)
plt.scatter([data[i][0] for i in range(len(data))],[data[i][1] for i in range(len(data))])
plt.plot([clipping_wnd[0][0],clipping_wnd[0][1]],[clipping_wnd[1][0],clipping_wnd[1][0]])
plt.plot([clipping_wnd[0][0],clipping_wnd[0][1]],[clipping_wnd[1][1],clipping_wnd[1][1]])
plt.plot([clipping_wnd[0][0],clipping_wnd[0][0]],[clipping_wnd[1][0],clipping_wnd[1][1]])
plt.plot([clipping_wnd[0][1],clipping_wnd[0][1]],[clipping_wnd[1][0],clipping_wnd[1][1]])


#변환 후 Point와 클리핑 window를 확인합니다.
plt.figure(figsize = [5,5])
plt.xlim(-3,3)
plt.ylim(-3,3)
plt.scatter([trans_data[i][0] for i in range(len(data))],[trans_data[i][1] for i in range(len(data))])
plt.plot([-1,1],[-1,-1])
plt.plot([-1,-1],[-1,1])
plt.plot([-1,1],[1,1])
plt.plot([1,1],[-1,1])

 

728x90
반응형

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

9. 2차원 선분 클리핑  (0) 2021.02.22
7. Color의 표현  (0) 2021.02.16
6. 채색 알고리즘(수정중)  (0) 2021.02.15
5. 기하변환 3(복합기하변환, 아핀변환)  (0) 2021.02.13
4. 기하변환2(동차좌표ver)  (0) 2021.02.12
공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함