https://color-change.tistory.com/54

 

(기하와 벡터) 회전변환 식 유도

::(기하와 벡터) 회전변환 식 유도:: - 개념, 공식, 증명, 유도 이 포스팅은 기하와 벡터의 회전변환 공식을 유도하는 글 입니다. 회전변환은 고교 수학(자연계) 기하와 벡터 과목의 전반부에서 처

color-change.tistory.com

'Directx12 > 기본이론' 카테고리의 다른 글

전치행렬, 단위행렬, 행렬식, 딸림행렬, 역행렬  (0) 2022.10.29
행렬 대수  (0) 2022.09.05
외적 , 직교화 , 점  (0) 2022.07.21
내적, 직교투영 , 직교화  (0) 2022.07.18
벡터의 길이와 단위벡터  (0) 2022.07.17

1.  전치행렬

행렬의 전치(transpose), 즉 전치행렬은 행렬의 행들과 열들을 맞바꾼 것이다. 따라서 m x n 행렬의 전치는  n x m 행렬이다. 행렬 M의 전치행렬은 다음과 같이 표기한다.

행렬 M의 전치행렬

다음과 같이 행과 열을 바꿉니다.

1행 -> 1열 , 2행 -> 2열, 3행 -> 3열... 이렇게 위치를 바꿉니다.

 

전치행렬에는 다음과 같은 유용한 성질이 있다.

 

2. 단위행렬

단위행렬(identity matrix) 이라고 부르는 특별한 행렬이 있다. 열 수과 행 수가 같은 정사각형의 행렬을 정방행렬(square matrix)이라고 부른다. 정방행렬의 좌상에서 우하로의 주된 대각선에 있는 성분들은 주대각(main diagonal) 성분이라고 부르는데, 단위행렬은 주대각 성분들만 1이고 나머지는 모두 0인 정방행렬이다.

 

    예를 들어 다음은 2 x 2, 3 x 3, 4 x 4 단위행렬이다.

   단위행렬은 곱셈의 항등원 역할을 한다.

   즉, A가  m  x n  행렬이고 B가 n x p 행렬, I가 n x n 단위행렬이면 아래와 같다.

   다른 말로 하면, 어떤 행렬에 단위행렬을 곱해도 그 행렬은 변하지 않는다. 단위행렬을 1의 행렬 버전이라고 생각하면 된다. 특히, M이 정방행렬일 때 단위행렬과의 곱셈은 교환법칙을 만족한다.

 

3. 행렬식

행렬식(Determinant)은 정방행렬을 입력받아서 실숫값을 출력하는 특별한 함수이다. 정방행렬 A의 행렬식을 흔히 det A로 표기한다. 기하학적으로 행렬식이 3차원 입체의 부피와 관련이 있다는 점과 행렬식이 선형변환 하에서 그 부피가 변하는 방식에 대한 정보를 제공한다는 점을 증명하는 것이 가능하다. 또한, 행렬식은 크라메르의 법칙(Cramer's rule)을 이용해서 1차 연립방정식을 푸는 데에도 쓰인다. 그러나 여기에서는 행렬의 역(역행렬)을 구할 때 행렬식이 쓰인다. 또한, 다음과 같은 정리가 있다.

  위의 정리를 이용하면 주어진 행렬의 역을 구하는 것이 가능한지를 손쉽게 판정할 수 있다. 행렬식을 정의하기 전에, 먼저 소행렬이라는 개념부터 살펴보자.

  3.1 소행렬

  예를 들어 보자.

소행렬 예제

   3.2 행렬식의 정의

     행렬의 행렬식은 재귀적으로 정의된다. 예를 들어 4 X 4 행렬의 행렬식은 3 X 3행렬의 행렬식들로 정의되고, 3 X 3 행렬의 행렬식은 2 X 2 행렬의 행렬식들로, 2 X 2 행렬의 행렬식은 1 X 1 행렬의 행렬식들로 정의된다. (1 x 1 행렬 A = [A¹¹]의 행렬식은 자명하게 정의되는데, 바로 det[A¹¹] = A¹¹이다. )

 

행렬식 공식

다음기회에 적자

'Directx12 > 기본이론' 카테고리의 다른 글

회전변환 식 유도 잘나온 사이트  (0) 2022.11.22
행렬 대수  (0) 2022.09.05
외적 , 직교화 , 점  (0) 2022.07.21
내적, 직교투영 , 직교화  (0) 2022.07.18
벡터의 길이와 단위벡터  (0) 2022.07.17

※ 행렬 사용 이유

    ▶ 3차원 컴퓨터 그래픽에서 행렬은 비례나 회전, 이동 같은 기하학적 변환을 간결하게 서술하는 데 쓰이며, 점이나 벡터의 좌표를 한 기준계에서 다른 기준계로 변환하는 데에도 쓰인다. 

 

※ 정의

    ▶ m x n 행렬 M은 m개의 행과 n개의 열로 이루어진 실수들의 정사각 배열이다. 행(row)들의 개수와 열(column)들의 개수의 곱(이를테면 4x4)을 행렬의 차원이라고 부른다. 행렬을 구성하는 수들을 성분(entry) 또는 원소(element; 또는 요소)라고 부른다. 

행렬의 한 성분을 나타낼 때에는 다음과 같이 나타낸다.

i는 행, j는 열이다.

 

    ▶ 다음 행렬들을 생각해 보자.

          1.  A = 4 x 4 행렬 , B =  3 x 2  행렬, u = 1 x 3 행렬, v = 4 x 1 행렬이다.

          2.  행렬 A의 4행(넷째 행) 2열(둘째 열)의 성분(-5)을 A₄₂라고 표기한다.

          3.  행렬 u , v는 각각 행과 열이 하나라는 점에서 특별한 행렬이다. 이런 종류의 행렬을 행벡터열벡터라고 부른다. 이것은 벡터를 행렬 형태로 표기할 때 쓰이기 때문이다. (예를 들어 벡터( x , y , z)를 행렬[ x , y , z]로 맞바꾸어 사용할 수 있다.)

 

    ▶ 종종 한 행렬의 행들을 벡터로들로 간주하는 것이 편리할 때가 있다. 예를 들어 행렬을 다음과 같이 표기할 수도 있다.

 

# 행렬의 상등, 덧셈, 스칼라 곱셈, 뺄셈 연산을 정의

    1. 두 행렬은 오직 대응되는 성분들이 상등일 때에만 상등이다.(두 행렬의 상등을 비교하려면 두 행렬의 행 개수들, 열 개수들이 같아야 된다.)

    2. 두 행렬을 더할 때에는 대응되는 성분들을 더한다. 따라서 차원이 같은 행렬들만 더할 수 있다.

    3. 행렬에 하나의 스칼라를 곱할 때에는 행렬의 모든 성분에 그 스칼라를 곱한다.

    4. 행렬의 뺄셈은 스칼라 곱셈과 행렬 덧셈으로 정의한다. 즉 (A - B = A + (-1 x B) = A + (-B))이다.

 

    ▶ 행렬 덧셈과 스칼라 곱셈은 성분별로 이루어지므로, 행렬 덧셈과 스칼라 곱셈도 실수의 덧셈 및 곱셈의 다음과 같은 성질들을 만족한다.

   

※ 행렬 곱셈

     # 정의 : 만일 A가 m x n 행렬이고 B가 n x p 행렬이면 둘의 곱 AB가 정의된다. 곱 AB는 하나의 m x p 행렬이다. 이를 C라고 할 때 , C의 ij번째 성분은 A의 i번째 행벡터와 B의 j번째 열벡터의 내적이다. 즉, 

행렬곱셈 정의

이다. 따라서 행렬 곱 AB가 정의되려면 A의 열 수와 B의 행수가 같아야 된다. 다른 말로 하면, A의 행벡터들의 차원과 B의 열벡터들의 차원이 같아야 된다. 이 차원들이 일치 하지않으면 내적이 말이 안된다.

Ex 1) 

    ▶ A의 행벡터들의 차원은 2이지만 B의 열벡터들의 차원은 3이므로, 두 행렬의 곱 AB는 정의되지 않는다. 좀 더 구체적으로, A의 첫 행벡터와 B의 첫 열벡터의 내적을 취할 수가 없다. 2차원 벡터와 3차원 벡터의 내적을 취할 수 없기 때문이다.

Ex 2) 

    ▶ 이 경우에는 곱 AB가 정의된다. A의 열 수와 B의 행 수가 같기 때문이다. 

     곱 BA는 정의되지 않음을 주목하기 발나다. B의 열 수와 A의 행수가 같지 않기 때문이다. 이 예에서 보듯이, 일반적으로 행렬 곱셈에는 교환법칙이 성립하지 않는다. 즉 AB ≠ BA이다.

 

# 벡터와 행렬의 곱셈

   다음과 같은 벡터 x 행렬 곱셈을 생각해 보자.

   이 경우 uA가 1 x 3 행벡터로 평가됨을 주목하기 바란다. 위의 내용을 다음 행렬곱셈으로 적용하면 다음과 같이 나온다.

행렬곱셈 정의

   이 것은 선형결합(linear combination, 일차결합)의 한 예이다. 이 식은 벡터 x 행렬 곱 uA가 행렬 A의 행벡터들과 벡터 u로 주어진 스칼라 계수 x , y , z의 선형결합에 해당함을 말해준다. 이 예는 1 x 3행벡터와 3 x 3 행렬의 경우이지만, 앞의 문장은 일반적으로도 참임을 주목하기 바란다. 즉 , 어떤 1 x n 행벡터 u와 어떤 n x m 행렬 A에 대해, 곱 uA는 A의 행벡터들과 u의 스칼라 계수들의 선형결합이다.

 

# 결합법칙

행렬 곱셈에는 몇 가지 편리한 대수적 성질들이 존재한다. 예를 들어 행렬 곱셈은 덧셈에 대한 분배법칙을 만족한다. 즉,  A(B + C) = AB + AC이고 (A + B)C = AC + AB이다. 더욱 중요한 것은, 행렬 곱셈이 다음과 같은 결합법칙을 만족한다는 것이다. 

※ 상수벡터

     ▶ 상수(const) XMVECTOR 인스턴스에는 반드시 XMVECTORF32 형식을 사용해야 한다.

     ▶ XMVECTORF32는 16바이트 경계에 정합되는 구조체로 , XMVECTOR로의 변환 연산자들을 제공한다.

     ▶ 정수 자료를 담은 상수 XMVECTOR를 생성하고 싶으면 XMVECTORU32를 사용한다.

   

    # 사용한 예시

코드
출력

 XMVECTORU32 는 본인이 잘못 사용하는건지 모르겠는데

여러가지 테스트 해보니 원하는 값이 안나온다.

 

※ 중복적재된 연산자들

     ▶ XMVECTOR에는 벡터 덧셈, 뺄셈, 스칼라 곱셈을 위해 중복적재(overloading)된 여러 연산자가 있다.

 

※ 기타 상수 및 함수

     ▶ π(원주율)가 포함된 여러 공식의 근삿값을 구할 때 유용한 다음과 같은 상수들을 정의한다.

     ▶  라디안(radian) 단위 각도와 도(degree) 단위 각도 사이의 변환을 위한 인라인 함수도 제공한다.

     ▶  최솟값/최댓값 함수들도 있다.

 

※ 설정 함수     

     ▶   DirectXMath 라이브러리는 XMVECTOR 객체의 내용을 설정하는 용도로 다음과 같은 함수들을 제공한다.

0벡터(0)를 돌려준다.

벡터 (1, 1, 1, 1)을 돌려준다.

벡터 (x, y, z, w)을 돌려준다.

벡터 (s, s, s, s)을 돌려준다.

벡터 (Vx, Vx, Vx, Vx)을 돌려준다.

벡터 (Vy, Vy, Vy, Vy)을 돌려준다.

벡터 (Vz, Vz, Vz, Vz)을 돌려준다.

     # 사용한 예시

 

※ 벡터 함수들

     ▶   DirectXMath 라이브러리는 다양한 벡터 연산을 위한 함수들을 제공한다. 다음은 그중 3차원 벡터를 위한 함수들이다. 2차원 벡터나 4차원 벡터를 위한 함수들도 물론 있는데, 함수 이름에 3대신 2나 4가 쓰인다는 점만 다를 뿐이다.

ll V ll 를 돌려준다.(절대값을 돌려준다.)

ll V ll ²  돌려준다.( 절대값의 제곱을 돌려준다.)

V₁ . V₂ 를 돌려준다.(내적을 돌려준다.)

V₁  x V₂ 를 돌려준다.(외적을 돌려준다.)

V / ll V ll 를 돌려준다.(정규화 벡터를 돌려준다.)

V에 수직인 벡터를 돌려준다.

V₁과 V₂ 사이의 각도를 돌려준다.

pParallel => projⁿ (V)를 돌려준다.

pPerpendicular => projⁿ (V)를 돌려준다.

V₁ = V₂를 돌려준다.

V₁ ≠ V₂를 돌려준다.

     # 사용한 예시

 

※ 부동소수점 오차

     ▶   컴퓨터에서 벡터를 다룰 때 주의해야 할 점이 있다. 바로,  부동소수점 수(Floating-pointnumber)들을 비교할 때 부동소수점의 부정확함을 반드시 고려해야 한다는 점이다.  당연히 같을 것 같은 두 부동소수점 수가 사실 약간 다를 수 있다. 예를들어 정규화된 벡터의 길이는 수학적으로 정확히 1이어야 하지만, 컴퓨터 프로그램 안에서 그 길이는 근사적으로만 1이다. 더 나아가서 , 임의의 실수 p에 대해  1^p = 1이지만, 근삿값으로만 표현되는 부동소수점 연산에서는 거듭제곱 과정에서 오차가 증가한다. 즉, 수치 오차가 누적되는 것이다. 다음은 이러한 개념을 보여주는 짧은 프로그램이다.

     ▶   부동소수점은 이러한 부정확함 때문에 두 부동소수점 수의 상등을 판정할 때에는 두 수가'근사적으로' 같은지를 보아야 한다. 이를 위해, 허용 오차로 사용할 아주 작은 수인 엡실론(epsilon)을 정하고 , 그 값을 이를테면 Epsilon이라는 상수로 코드 안에 정의해 둔다. 만일 거리가 Epsilon보다 작으면 두 수는 근사적으로 상등인 것이다.

다음은 Epsilon을 이용해서 두 부동소수점 수의 상등을 판정하는 방법을 보여주는 함수이다.(만든 것)

DirectXMath 라이브러리에는 두 벡터의 상등을 판정하는 함수가 있다.(라이브러리에서 제공)

     

 

          

'Directx12 > DirectX 내용' 카테고리의 다른 글

DirectXMath 라이브러리의 벡터(2)  (0) 2022.08.14
DirectXMath 라이브러리의 벡터(1)  (0) 2022.08.02

※ XMVECTOR 매개변수 전달.

   ▶  XMVECTOR  인스턴스를 인수로 해서 함수를 호출 할 때, 효율성을 위해서 XMVECTOR 값이 스택이 아니라 SSE/SSE2 레지스터를 통해서 함수에 전달되게 해야 한다. 그런 식으로 전달할 수 있는 인수의 개수는 플랫폼(32 비트 Windows , 64비트 Windows , Windows RT등)과 컴파일러에 따라 다르다.

   그래서 플랫폼/컴파일러에 대한 의존성을 없애기 위해서 XMVECTOR 매개변수에 대해  FXMVECTOR, GXMVECTOR, HXMVECTOR, CXMVECTOR라는 형식들을 사용해야 한다. 또한 , SSE/SSE2 레지스터 활용을 위한 호출 규약 역시 컴파일러에 따라 다를 수 있는데, 그러한 의존성을 없애려면 함수 이름 앞에 반드시 XM_CALLCONV라는 호출 규약 지시자를 붙여야 한다.

 

    # XMVECTOR 매개변수의 전달에 관란 규칙을 요약하자면 다음과 같다.

       1. 처음 세 XMVECTOR 매개변수에는 반드시 FXMVECTOR 형식을 지정해야 된다.

       2. 넷째 XMVECTOR 매개변수에는 반드시 GXMVECTOR 형식을 지정해야 한다.

       3. 다섯째와 여섯째 XMVECTOR 매개변수에는 반드시 HXMVECTOR 형식을 지정해야 한다.

       3. 그 이상의 XMVECTOR 매개변수들에는 반드시 CXMVECTOR형식을 지정해야 된다.

   

   ▶  예를들어, 32 비트 Windows에서 __fastcall 호출 규약을 지원하는 컴파일러와 좀 더 최신의 __vectorcall 호출 규약을 지원하는 컴파일러는 이 형식들을 다음과 같이 정의한다.

 

          // 32 -bit Window __fastcall은 처음 세 XMVECTOR 인수를 

          // 레지스터들을 통해서 전달하고 , 나머지는 스택을 사용한다.

          typedef const XMVECTOR FXMVECTOR;

          typedef const XMVECTOR& GXMVECTOR;

          typedef const XMVECTOR& HXMVECTOR;

          typedef const XMVECTOR& CXMVECTOR;

 

          // 32 -bit Window __vectorcall은 처음 여섯 XMVECTOR 인수를

          // 레지스터들을 통해서 전달하고, 나머지는 스택을 사용한다.

          typedef const XMVECTOR FXMVECTOR;

          typedef const XMVECTOR GXMVECTOR;

          typedef const XMVECTOR HXMVECTOR;

          typedef const XMVECTOR& CXMVECTOR;

 

    #  사용한 예시

규칙을 사용한 코드

   ▶  XMVECVOR 매개변수 중간에 XMVECTOR 매개변수가 아니여도 규칙은 똑같이 적용한다. 

    #  사용한 예시

매개변수 규칙이 똑같이 적용되는 코드

 

   ▶  생성자에 대해서는 조금 다른 규칙이 있다.        

         1. 처음 세 XMVECTOR 매개변수에는  FXMVECTOR 형식을 지정해야 된다.         

         2.  그 나머지에는  CXMVECTOR를 사용을 권한다.

         3.  생성자에는 XM_CALLCONV를 사용하지 말아야 된다.

 

    #  사용한 예시

생성자의 규칙이 적용된 코드

- 지금까지 말한 XMVECTOR 매개변수 전달 규칙은 '입력' 매개변수들에 적용된다. '출력' XMVECTOR 매개변수(XMVECTOR& 또는 XMVECTOR*)는 SSE/SSE2 레지스터를 사용하지 않으므로, 그냥 XMVECTOR가 아닌 매개변수들과 동일하게 취급된다.

'Directx12 > DirectX 내용' 카테고리의 다른 글

DirectXMath 라이브러리의 벡터(3)  (0) 2022.08.15
DirectXMath 라이브러리의 벡터(1)  (0) 2022.08.02

※ DirectXMath 란?

   - WIndow 8 이상에서 DirectX3D 응용 프로그램을 위한 표준 3차원 수학 라이브러리이다. Windows SDK의 일부인 이 라이브러리는 SSE2(Streaming SIMD Extensions 2) 명령 집합을 활용한다.

 

   ▶  SIMD (single instruction multiple data)란?

        하나의 명령으로 여러데이터를 처리한다.

   ▶  SSE2(Streaming SIMD Extensions 2)란?

        128비트 너비의 SIMD레지스터를 이용해서 float, int와 같은 32비트 데이터 4개를 한꺼번에 처리한다. 

        그래서 벡터계산을 아주 유용하게 할 수 있다.

# 참고자료

https://m.blog.naver.com/fs0608/221650925743

 

SIMD (Single Instruction Multiple Data)에 대한 집중탐구!

안녕하세요~! 오늘은 파수테크 블로그 첫번째 시간으로 SIMD (Single Instruction Multiple Data)...

blog.naver.com

https://www.secmem.org/blog/2022/02/15/Intel-Intrinsics-Guide/   

 

Intel Intrinsics(SIMD) 가이드

1. Introduction 우리가 주로 사용하는 Intel(AMD) 아키텍쳐에서는 SIMD(Single Instruction Multiple Data)를 이용할 수 있습니다. SIMD는 말 뜻 그대로 하나의 명령을 통해 여러 값의 연산을 동시에 처리하는 명령

www.secmem.org

 

   ▶  X86(32bit)에서 SSE2 사용 할때 주의사항

         - SSE2를 활성화 해야된다. x64는 상관없이 다된다.

           ( 프로젝트속성 > 구성 속성 > C/C++ > 코드 생성 > 고급 명령 집합 사용)

 

※ 사용해보기.(여기에선 visual studio community 2019로 작업한다.)

       ▶  빈 프로젝트를 만든다.

     

     ▶  C++ 소스파일을 만든다

 

     ▶  여기서 X84로 사용해서 SSE2사용 체크를 한다.       

 

     ▶  DirectXMath.h 추가 및 DirectX 네임스페이스 사용

        여기까지 됬으면 사용할 준비는 끝났다.

 

※  벡터 형식들 알아보기

         ▶  XMVECTOR 

               - DirectXMath에서 핵심 벡터 형식은 SIMD 하드웨어 레지스터에 대응되는 XMVECTOR이다.

                 이 XMVECTOR는 128비트의 크기의 32비트 부동소수점 값 4개로 구성되어있고 한번 명령

                  으로 4개를 처리할 수 있다. 정의는 다음과 같다.

 

               typedef __m128 XMVECTOR;

 

                  SIMD의 장점을 쓰려면 벡터가 XMVECTOR 형식으로 바껴야 된다.

                  이 형식으로 3차원 ,2차원 값을 처리할 수 있다. 쓰이지 않는 성분들은 0으로 설정하면 된다.

 

               - XMVECTOR는 16바이트에 경계에서 정합(alignment) 되어야 한다. 그래서 자동으로 정합이

               일어나는 지역변수나 전역변수에서 사용된다.

 

         ▶  XMFLOAT2 , XMFLOAT3 , XMFLOAT4

               - 벡터 성분들을 담는 구조체이다. 클래스 멤버 자료형으로 사용되는 걸 권장된다.

                 1) FLOAT2 : 2차원 벡터값을 담는 구조체 

                 2) FLOAT3 : 3차원 벡터 값을 담는 구조체

                 3) FLOAT4 : 4차원 벡터 값을 담는 구조체

                

                FLOAT2 , FLOAT3, FLOAT4 벡터 연산은 가능하다. 하지만 SIMD의 장점을 사용해서 계산하는

               것이 효과적이기 때문에 XMVECTOR 형식으로 변환해야 한다.

 

         ▶  XMLoadFloat2 , XMLoadFloat3 , XMLoadFloat4

               - XMLoadFloat는 XMFLOAT -> XMVECTOR에 변환해서 저장을 할 수 있게 도와주는 함수이다. 

                이것을 XMFLOAT -> XMVECTOR에 적재한다고 표현한다.

 

         ▶  XMStoreFloat2 , XMStoreFloat3 , XMStoreFloat4

               - XMStoreFloat는 XMVECTOR -> XMFLOAT에 변환해서 저장을 할 수 있게 도와주는 함수이다.

                이것을 XMVECTOR-> XMFLOAT에 저장한다고 표현한다.

 

         ▶  XMVectorGetX , XMVectorGetY , XMVectorGetZ , XMVectorGetW                

               -  이것은 XMVECTOR의 특정 성분만 읽고 싶을 때 사용하는 함수들이다.

         ▶  XMVectorSetX , XMVectorSetY , XMVectorSetZ , XMVectorSetW                

               -  이것은 XMVECTOR의 특정 성분만 변경하고 싶을 때 사용하는 함수들이다.

 

           # 실제 사용       

                   

 

                # 정리

               1. 지역변수나 전역변수에는 XMVECTOR를 사용한다.

               2. 클래스 자료 멤버에 XMFLOAT2 , XMFLOAT3 , XMFLOAT4를 사용한다.

               3. 계산을 수행하기 전에 적재(Load) 함수들을 이용해서 XMFLOAT 을 XMVECTOR로 변환한다.

               4. XMVECTOR 인스턴스들로 계산을 수행한다.

               5. 저장 함수들을 이용해서 XMVECTOR를 XMFLOAT으로 변환한다.

 

 

 

 

'Directx12 > DirectX 내용' 카테고리의 다른 글

DirectXMath 라이브러리의 벡터(3)  (0) 2022.08.15
DirectXMath 라이브러리의 벡터(2)  (0) 2022.08.14

+ Recent posts