Computer Graphics 4. Geometry Transformation
숙명여자대학교 컴퓨터 그래픽스 수업 - 유석종 교수님
# Object Modeling
- Surface Representation: 물체의 표면을 표현
> Polygon, Mesh
> Rectangular mesh: 네 점이 한 평면 위에 존재한다는 것을 보장하지 못함
> Triangular mesh: 삼각형은 네 점이 한 평면 위에 존재한다는 것을 보장할 수 있음,
높은 정밀도, 삼각형 분할을 위한 두 배의 처리 시간
* 도형이 많을수록 부드럽게 표현 가능
# Rendering
- 조명, 음영, 질감, 가시성 등과 같은 물리적 효과를 계산하여 객체 모델에서 실제 장면을 그림
> wireframe rendering: 모델링 단계를 위해 빠름
> solid rendering: 디자인 검토를 위해 느림
# Vector Space
- Scalar: 크기만을 가지고 실수로 표현 / 방향이 없음
- Vector: 크기와 방향을 동시에 가지지만 origin이 없음
> 연산: 역, 스칼라 곱셈, 벡터 덧셈
> 객체 정점 정의 및 그래픽 렌더링 계산에 사용됨
* 벡터는 조명에 의해서 surface rendering을 하는데에 중요. 면이 어느 방향을 향하고 있는지에 대해 표현
# Affine Space
- 동일한 크기 벡터는 origin의 부재로 동일한 것으로 간주됨
> 한계점 크기와 방향만 같으면 모두 같은 벡터로 인식
- affine space
> 점의 개념에 의해 추가된 확장된 벡터 공간
> vector의 origin을 나타낼 수 있음
- affine operations
> V = A + B : 벡터 사이의 덧셈
> V' = 2V : 백터와 스칼라 사이의 곱셈
> Q = V + P : 벡터 및 점은 새 점을 정의
* V = Q = P
# Coordinate System
- 벡터는 주축(x, y, z)에 대해 단위 벡터(v1, v2, v3)로 나타내 짐
> V = x*v1 + y*v2 + z*v3
- 좌표계
> origin과 basis vector로 이루어진 프레임 → 있으면 임의의 점 정의 가능
→ C = (r, v1, v2, v3)
> 점은 좌표계에 의해 표현됨
→ P = r + 4*V1 + 2*V2 + V3
# Homegeneous Coordinate System
- 동차 좌표계: 차원이 같음
- 점과 벡터를 나타내는 affine 공간을 위한 4D 좌표계
- 점은 점의 origin을 보존해야 함
> P(4, 2, 1, 1) → 4차원의 동차 좌표계로 표현
> P = 4*V1 + 2*V2 + V3 + 1*r → r: origin
- vector는 origin이 없음
> V(4, 2, 1, 0)
> 4*V1 + 2*V2 + V3 + 0*r
* 마지막 차원의 값을 가지고 점과 벡터를 구분할 수 있음
# Modeling Transformation
- 개체의 모델링 변환
> Translation: 이동 변환
> Rotation: 회전
> Scaling: 크기 변환
- 객체를 변환하려면 객체 꼭짓점과 변환 matrix 사이의 곱셈에 의해 수행됨
# 2D Translation
- P(x, y): 정점 matrix
- T (Tx, Ty): 이동 변환 matrix
- P’ (x’, y’) = T (Tx, Ty) ∙ P (x, y)
- x' = x + Tx
- y' = y + Ty
* 이동: 새로운 좌표점을 구하는 것
# 3D Translation
- P (x, y, z) : 정점 matrix
- T (Tx , Ty , Tz) : 이동 변환 matrix
- P’ (x’, y’, z’) = T ∙ P : T의 이동 변환 후의 점
- x' = x + Tx , y' = y + Ty , z' = z + Tz
# 2D Rotation
* 원점 회전만 존재
- R: 회전 변환 matrix
- P': R ∙ P
- x: rcosθ, y=rsinθ
# 3D Ratation
- x, y, z 축 회전
- θ: 회전 각
- right-hand system: OpenGL
- left-hand system: Unity, DirectX
- Rz: Z-Rotation
- Z 좌표계에서는 변화가 없음
- x축 회전
- y축 회전
# Scaling
- Uniform vs. Non-uniform scaling
# Composite Transformation
- 복합 변환
(a): 원래 큐브의 위치
(b): 원점을 기준으로 회전 origin-based rotation
(c): 중심을 기준으로 회전 pivot point rotation
- 변환 순서(원리는 WCS에 기반 (World Coordinate System))
> Translate(T1) → Rotate(R) → Translate(T2)
- Matrix 곱셈 in OpenGL (객체 기반한 MCS)
* MCS: 개별 물체 당 주어진 좌표계 Modeling Coordinate System
> P' = T2 ∙ R ∙ T1 ∙ P // 교환 법칙 성립 X
> 복합 변환의 사전 컴퓨팅은 전체 처리 시간을 절약할 수 있음
> P' = C∙P // C = T2∙R∙T1
# Pivot Point Rotation
- 피벗 지점이 원점과 겹치도록 개체를 이동 T(-P)
- 회전축에서 물체를 회전: R
- 회전된 물체를 원래 위치인 T(P)로 다시 이동
- 행렬은 변환의 역순으로 곱함
# Transformation Order
- matrix의 곱셈은 교환 법칙이 성립하지 않음
> translate → rotation (Rz ∙ Tx) // left
> rotate → translate (Tx ∙ Rz) // right
# Reflection
(a) X-reflection (b) Y-reflection (c) Origin reflection
# Composite Reflection
- 선 y=x에 대하여 반사 (WCS에 기반하여)
> 원점에서 점을 45도 회전 (R)
> 점의 Y축 반사 (Y)
> 원점에서 점을 -45도 회전 (-R)
> P' = R ∙ Y ∙ -P
# Modeling Coordinate System
- MCS
> 모델링 단계에서 사용되는 객체별 좌표
> 임의의 좌표 원점 및 단위를 가짐
> 여러 개 있을 수 있음(물체 수만큼 존재) * 단위도 다를 수 있음
# WCS, MCS, and VCS
- World Coordinate System
> 여러 MCS를 하나로 통합
- View Coordinate System
> 카메라에 정의된 좌표계
> 시야 공간이 veiwport로 이전됨
# Matrix Multiplication
- 물체의 꼭짓점 좌표는 trans와 분리됨
>matrix는 OpenGL을 따름
- 객체가 변환될 때, 정점 행렬에 변환 행렬을 곱하여 WCS 위치를 얻음
- P'wcs = Translate * Pmcs
- Rotation
> MCS는 객체와 회전됨
- Scaling
> MCS와 WCS unit 사이의 비율을 바꿈
> x 축에서 2배로 확장 → WCS : MCS = 2 : 1
> P'wcs(4, 2, 0) = S(2, 2, 1) * Pmcs(2, 2, 0)
* object의 정점 좌표는 분리되어 관리되다가 물체를 그리는 순간에 곰셈이 발생
# ModelView Matrix
- Modeling Transformation
> Translation, rotation, scaling of an object
- Viewing Transformation
> Viewing 좌표계 시스템을 정의하기 위해
> 카메라의 위치와 방향에 의해서 정의됨
- ModelView 시스템 matrix는 두 가지(modeling&viewing) 변환들을 관리함
# Matrix Stack
- 변환이 발생할 때, 변환 matrix는 System Matrix Stack에 push됨
glMatrixMode(GLenum mode)
> GL_MODELVIEW
> GL_PROJECTION
> GL_TEXTURE
- matrix 스택은 연속적인 변환 matrix들을 관리함
> matrix stack의 top element는 CTM을 의미함
glPushMatrix() # CTM의 복사본을 CTM을 저장하기 위해 matrix에 저장
glPopMatrix() # 최근 CTM을 복구하기위해 top CTM을 pop함
> (b) 위치로 돌아가는 방법: 위치를 알 수 있는 방법이 없어 돌아갈 수 없음
→ 그래서 stack을 사용하는 것
# Object-based MCS
- OpenGL
glMatrixMode(GL_MODELVIEW)
glLoadIdentity( )
glRotatef(45, 0.0, 0.0, 1.0)
glTranslatef(10.0, 0.0, 0.0)
glVertex3f(x, y, z)
- OpenGL 코드 순서대로 해석하는 것
> MCS를 객체와 회전
> 최근 MCS위에서 MCS를 이동 변환
> 최종 MCS의 origin위에 객체를 그림
# Origin-based WCS
- OpenGL
glMatrixMode(GL_MODELVIEW)
glLoadIdentity( )
glRotatef(45, 0.0, 0.0, 1.0)
glTranslatef(10.0, 0.0, 0.0)
glVertex3f(x, y, z)
- OpenGL 코드의 역순으로 해석하는 것
> MCS를 WCS origin으로부터 이동 변환
> WCS origin위에서 MCS 회전
> 마지막 MCS의 orgin에 객체를 그림
# CTM
- 현재 변환 matrix
> 변환이 발생하면, CTM. 즉, 시스템 matrix stack의 top element를 업데이트함
> 객체의 vertex matrix는 그려지기 전에 CTM에 의해 곱해짐
- CTM Initializtion
glLoadIdentity()
- CTM accumulation
> 오른쪽에서 CTM으로 변환이 누적됨
> CTM = CTM · M
> ex) glTraslatef(1, 2, 0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() # CTM initialized
glScalef(sx, sy, sz)
glRotatef(theta, vx, vy, vz)
glBegin(GL_POINTS)
glVertex3f(x, y, z)
glEnd()
# Hierarchical Modeling
void drawArm( )
glMatrixMode(GL_MODELVIEW)
glLoadIdentity( ) # CTM 초기화
Draw_Body( ) # 몸체
glPushMatrix( ) # CTM 저장
GoToLeftShoulderCoordinates( ) # 어깨 위치 이동
Draw_UpperArm( ) # 위팔 그리기
glPushMatrix( ) # CTM 저장(어깨)
GoToElbowCoordinates( ) # 팔꿈치 위치 이동
Draw_LowerArm( ) # 아래팔 그리기
glPushMatrix( ) # CTM 저장(팔꿈치)
GoToWristCoordinates( ) # 손목 위치
Draw_Hand( ) # 손 그리기
glPopMatrix( ) #팔꿈치 위치 복원
glPopMatrix( ) #어깨 위치 복원
# 오른쪽 팔을 그리기 위한 함수…
glPopMatrix( ) # 몸체 위치 복원
# Solar System
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
# 계층적 구조
class SolarSystem:
def __init__(self): # 초기화
self.angle1 = 0.0
self.angle2 = 0.0
def draw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # transformation 초기화
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glColor3f(1.0, 0.3, 0.3)
glutWireSphere(0.2, 20, 16) #sun
glPushMatrix()
glRotatef(self.angle1, 0.0, 1.0, 0.0) # 지구의 공전
glTranslatef(0.7, 0.0, 0.0) # 지구와 태양의 거리
glRotatef(self.angle2, 0.0, 1.0, 0.0) # 지구의 자전
glColor3f(0.5, 0.6, 0.7)
glutWireSphere(0.1, 10, 8) # Earth
glPushMatrix() # 지구의 위치 저장
glRotatef(self.angle2, 0.0, 1.0, 0.0) # 달의 공전
glTranslatef(0.2, 0.0, 0.0) # 지구와 달의 거리
glColor3f(0.9, 0.8, 0.2)
glutWireSphere(0.04, 10, 8) # Moon
glPopMatrix() # 지구의 위치로 돌아감
glPopMatrix() # 태양의 위치로 돌아감
glutSwapBuffers()
def MyKeyboard(self, key, x, y):
if key==b'd':
self.angle1 += 5 # 공전 각도 증가
if self.angle1 >= 360.0: self.angle1 = 0.0
glutPostRedisplay()
elif key==b't':
self.angle2 -= 2 # 자전 각도 감소
if self.angle2 <= 0.0: self.angle2 = 360.0
glutPostRedisplay()
def main(self):
glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) # 애니메이션
glutInitWindowSize(500, 500)
glutInitWindowPosition(0,0)
glutCreateWindow("OpenGL Solar System")
glClearColor(0.0, 0.0, 0.0, 1.0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)
glutDisplayFunc(self.draw)
glutKeyboardFunc(self.MyKeyboard)
glutMainLoop()
return 0
s = SolarSystem()
s.main()
# Structure-Deforming Transformation
- 구조가 변경되지 않는 변환
> scaling, translate, rotate
- 구조가 변경되는 변환
> tapering: (a) → (b)
z축을 따라 객체의 크기가 조정됨
> bending: (a) → (c)
축을 따라, 물체가 구부러짐
> twisting: (d) → (e)
z축을 따라, 회전 각도가 증가
# Transformation Classes
- Rigid Body Transformation (강세 변환)
> 물체의 모양이 보존됨
> 이동 변환, 회전
- Similarity Transformation
> polygon 간의 각도 및 vertex 간의 거리를 유지
> 강세 변환 + uniform scaling인 반사(reflection)
- Affine Transformation
> 선, 다각형, 곡면 평행선과 같은 객체 모양을 유지
> similarity transformation + non-uniform scaling, shearing(밀림)
- Perspective Transformation (원근 변환)
> 평행선이 서로 만남
> 직선을 유지
- Linear Transformation
> x, y, z의 선형 조합으로 x' = ax + by+ cz로 표시됨
> 직선을 유지함
> affine + perspective trans
- Non-linear transformation (비선형 변환)
> x' = ayx + by^2 + cz/x
> 상수간 곱셈, 1차 함수가 아님
> 구조 변환 trans이므로 직선 유지 보장이 없음
# Viewing Transformation
- Viewing Coordinate System (VCS)
> 카메라 view volume 정의 설정 변환
> 카메라 위치 및 방향에 따라 정의됨
> 카메라가 보는 것은 변환의 역변환임
> modelview 변환 matrix가 관리
model transformation matrix + view transformation matrix
# Camera rotation
- Tilting: X축 회전 # 위/아래
- Panning: Y축 회전 # 좌/우
- Rolling: Z축 회전 # 시계 방향 회전/반시계 방향 회전
- Dolling: 카메라 Zoom-in/out
# Flight Angles
- right-hand system
- 평면의 방향은 세 각도로 명시됨
- Roll: Z축 회전 각도 (second)
- Pitch: X축 회전 각도 (third)
- Yaw: Y축 회전 각도 (last)
# GL VCS
glutLookAt (eyex, eyey, eyez, # Camera position
atx, aty, atz, # Camera focus
upx, upy, upz) # Camera orientation
glutLookAt (0.0, 0.0, 0.0, 0.0, 0.0, -1,0, 0.0, 1.0, 0.0) # default
# Viewing and Modeling Transformtion
glMatrixMode(GL_MODELVIEW)
glLoadIdentity( ) # I
gluLookAt(0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # V
# view transformation matrix 생성 (veiew point, target, up vector)
glTranslatef (5.0, 5.0, 0.0) # T1
glTranslatef (4.0, 2.0, 0.0) # T2
glRotatef (45, 0.0, 0.0, 1.0) # R
glutWireCube(1.0) # PMC
- Pvcs = V ˙ Pwcs
= V ˙ T1 ˙ T2 ˙ R ˙ Pmcs
# Camera Coordinate System
gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz)
- 축: u, v, n
- n = eye-at
- u = up * n # crdss product 외적
- v = n * u
- origin: eye(looking in the direction -n)
# Cross Product
- 외적
- a * b = |a| * |b| * sinθ
'Study > Computer Graphics' 카테고리의 다른 글
[CG] 5. Projection (0) | 2021.10.19 |
---|---|
[CG] 3-2. OpenGL Event Handling (0) | 2021.10.08 |
[CG] 3-1. Graphic Library (0) | 2021.10.06 |
[CG] 2-2. Color Models (0) | 2021.10.04 |
[CG] 2-1. Graphics System (0) | 2021.09.20 |