X 방향으로 벡터를 10 단위로 변환하려면 왜 행렬을 사용해야합니까?
mat [0] [0]에 10을 더하면 같은 결과를 얻을 수 있습니다.
답변
예, 번역 할 경우 벡터를 추가 할 수 있습니다. 행렬을 사용하는 이유는 서로 다른 결합 된 변환을 처리 할 수있는 균일 한 방법으로 귀결됩니다.
예를 들어 회전은 일반적으로 행렬을 사용하여 수행되므로 (회전을 처리하는 다른 방법은 @MickLH 주석 확인) 여러 변형 (회전 / 번역 / 스케일링 / 투영 등)을 균일 한 방식으로 처리하려면, 행렬로 인코딩해야합니다.
더 기술적으로 말하면; 변환은 점 / 벡터를 다른 점 / 벡터에 매핑합니다.
p` = T(p);
여기서 p`는 변환 된 점이고 T (p)는 변환 함수입니다.
행렬을 사용하지 않는 경우 여러 변환을 결합하려면이 작업을 수행해야합니다.
p1 = T (p);
p 최종 = M (p1);
행렬은 여러 유형의 변환을 단일 행렬 (예 : 아핀, 선형, 투영)로 결합 할 수 있습니다.
행렬을 사용하면 변형 체인을 결합한 다음 일괄 적으로 곱할 수 있습니다. 이것은 일반적으로 GPU에 의한 많은 사이클을 줄여줍니다 (@ChristianRau 덕분에 지적했습니다).
T 최종 = T * R * P; // 회전 프로젝트 번역
p 최종 = T 최종 * p;
GPU 및 일부 CPU조차도 벡터 연산에 최적화되어 있음을 지적하는 것이 좋습니다. SIMD 및 GPU를 사용하는 CPU는 설계 상 데이터 구동 병렬 프로세서이므로 행렬을 사용하면 하드웨어 가속에 완벽하게 맞습니다 (실제로 GPU는 매트릭스 / 벡터 연산에 적합하도록 설계되었습니다).
답변
당신이 할 모든 것이 단일 축을 따라 이동하고 다른 변형을 적용하지 않으면 제안하는 것이 좋습니다.
매트릭스를 사용하면 실제로 일련의 복잡한 연산을 쉽게 연결하고 동일한 객체를 여러 객체에 적용 할 수 있습니다.
대부분의 경우는 그렇게 간단하지 않으며 객체를 먼저 회전하고 월드 축 대신 로컬 축을 따라 변형하려는 경우 숫자 중 하나에 10을 더하고 정확하게 운동 할 수는 없습니다. .
답변
“왜”질문에 간결하게 대답하기 위해, 4×4 매트릭스는 회전, 변환 및 스케일링 작업을 모두 한 번에 설명 할 수 있기 때문입니다. 이들 중 하나를 일관된 방식으로 설명 할 수 있으면 많은 것이 간단 해집니다.
다른 종류의 변환은 다른 수학적 연산으로 더 간단하게 표현할 수 있습니다. 참고로 번역을 추가하면됩니다. 스칼라를 곱하여 균일 한 스케일링. 그러나 적절하게 제작 된 4×4 매트릭스는 무엇이든 할 수 있습니다. 따라서 4×4를 사용하면 코드와 인터페이스가 일관되게 훨씬 간단 해집니다. 이 4×4를 이해하는 데 약간의 복잡성을 지불하지만 많은 것들이 더 쉽고 빠릅니다.
답변
4×4 매트릭스를 사용하는 이유는 연산이 선형 변환 이기 때문 입니다. 이것은 동종 좌표 의 예입니다 . 2D 경우에서도 동일한 작업이 수행됩니다 (3×3 매트릭스 사용). 균일 한 좌표를 사용하는 이유는 한 번의 조작으로 3 개의 기하학적 형태 변형 을 모두 수행 할 수 있기 때문입니다. 그렇지 않으면 3×3 행렬 곱하기와 3×3 행렬 더하기 (변환을 위해)를 수행해야합니다. cegprakash 의이 링크 는 유용합니다.
답변
변환은 3D 행렬로 표현 될 수 없습니다
간단한 주장은 번역이 원점 벡터를 취할 수 있다는 것입니다.
0
0
0
원점에서 멀어 지려면 다음과 같이 말합니다 x = 1
.
1
0
0
그러나 다음과 같은 행렬이 필요합니다.
| a b c | |0| |1|
| d e f | * |0| = |0|
| g h i | |0| |0|
그러나 그것은 불가능합니다.
또 다른 논거는 Singular Value Decomposition theinging 인데, 이것은 모든 행렬이 2 개의 회전과 1 개의 스케일링 연산으로 구성 될 수 있다고 말합니다. 거기에 번역이 없습니다.
왜 행렬을 사용할 수 있습니까?
많은 모델링 된 객체 (예 : 자동차 섀시) 또는 모델링 된 객체 (예 : 자동차 타이어, 구동륜)의 일부는 견고합니다. 꼭지점 사이의 거리는 절대 변하지 않습니다.
우리가 그들에게하고 싶은 유일한 변화는 회전과 번역입니다.
행렬 곱셈은 회전과 변환을 모두 인코딩 할 수 있습니다.
회전 행렬에는 다음과 같은 명시적인 공식이 있습니다. 예를 들어, 각도 a
에 대한 2D 회전 행렬 의 형식은 다음과 같습니다.
cos(a) -sin(a)
sin(a) cos(a)
3D 와 유사한 공식 이 있지만 3D 회전에는 1 대신 3 개의 매개 변수가 사용됩니다 .
번역은 간단하지 않으며 나중에 논의 될 것입니다. 이것이 4D 매트릭스가 필요한 이유입니다.
행렬을 사용하는 것이 왜 멋진가요?
여러 행렬의 구성은 행렬 곱셈에 의해 미리 계산 될 수 있기 때문 입니다.
예를 들어, v
자동차 섀시의 천 벡터 를 행렬 로 변환 한 T
다음 행렬 R
대신 회전 하는 경우 :
v2 = T * v
그리고:
v3 = R * v2
각 벡터에 대해 미리 계산할 수 있습니다.
RT = R * T
그런 다음 모든 정점마다 하나의 곱셈을 수행하십시오.
v3 = RT * v
더 좋은 방법 : 만약 우리가 차에 상대적인 타이어와 구동 휠의 꼭지점을 배치하고 싶다면, 우리는 이전의 행렬 RT
에 자동차 자체에 대한 행렬을 곱하면 됩니다.
이것은 당연히 행렬 스택 을 유지 관리합니다 .
- 섀시 매트릭스 계산
- 타이어 매트릭스로 곱하기 (푸시)
- 타이어 매트릭스 제거 (팝)
- 휠 매트릭스를 구동하여 곱하기 (푸시)
- …
1 차원을 추가하면 문제가 해결되는 방법
시각화가 더 쉬운 1D에서 2D 로의 사례를 고려해 봅시다.
1D의 행렬은 하나의 숫자이며 3D에서 볼 수 있듯이 변환은 할 수없고 스케일링 만 할 수 있습니다.
그러나 추가 차원을 다음과 같이 추가하면
| 1 dx | * |x| = | x + dx |
| 0 1 | |1| | 1 |
그런 다음 새로운 추가 차원에 대해 잊어 버립니다.
x + dx
우리가 원하는대로
이 2D 변형은 전단 변형 이라는 이름을 갖도록 매우 중요합니다 .
이 변환을 시각화하는 것이 좋습니다.
이미지 소스 .
모든 수평선 (고정 y
)이 어떻게 변환 되는지 확인하십시오 .
방금 y = 1
새로운 1D 라인으로 라인을 가져 와서 2D 매트릭스로 변환했습니다.
사물의 형태는 4D 전단 매트릭스와 함께 3D와 유사합니다.
| 1 0 0 dx | | x | | x + dx |
| 0 1 0 dy | * | y | = | y + dy |
| 0 0 1 dz | | z | | z + dz |
| 0 0 0 1 | | 1 | | 1 |
그리고 우리의 오래된 3D 회전 / 스케일링은 이제 형태가 있습니다 :
| a b c 0 |
| d e f 0 |
| g h i 0 |
| 0 0 0 1 |
이 Jamie King 비디오 자습서 도 시청할 가치가 있습니다.
적절한 공간
공간 정의는 모든 3D 선형 변환 (행렬 곱셈)과 4D 전단 (3D 변환)으로 생성 된 공간입니다.
전단 행렬과 3D 선형 변환을 곱하면 항상 다음과 같은 형식을 얻습니다.
| a b c dx |
| d e f dy |
| g h i dz |
| 0 0 0 1 |
이것은 3D 회전 / 스케일링 및 변환을 수행하는 가장 일반적인 가능한 아핀 변환입니다.
중요한 속성 중 하나는 2 개의 아핀 행렬을 곱하면 다음과 같습니다.
| a b c dx | | a2 b2 c2 dx2 |
| d e f dy | * | d2 e2 f2 dy2 |
| g h i dz | | g2 h2 i2 dz2 |
| 0 0 0 1 | | 0 0 0 1 |
우리는 항상 다른 형태의 아핀 행렬을 얻습니다.
| a3 b3 c3 (dx + dx2) |
| d3 e3 f3 (dy + dy2) |
| g3 h3 i3 (dz + dz2) |
| 0 0 0 1 |
수학자들은이 속성 폐쇄 라고 하며 공간을 정의해야합니다.
우리에게는 최종 변환을 행복하게 계산하기 위해 행렬 곱셈을 계속 수행 할 수 있다는 것을 의미합니다. 따라서 더 일반적인 4D 선형 변환을 얻지 않고 사용 된 행렬을 먼저 사용하십시오.
절두체 투영
그러나 우리가 항상하는 또 하나의 중요한 변환이 있습니다. 즉 glFrustum
, 객체를 2 배 더 멀리 만드는 것은 2 배 더 작아 보입니다.
먼저 https : glOrtho
//.com/questions/2571402/explain-the-usage-of-glortho/36046924#36046924 glFrustum
에서 vs 에 대한 직관을 얻으십시오 .
glOrtho
translations + scaling만으로 수행 할 수 있지만 glFrustum
행렬로 어떻게 구현할 수 있습니까?
한다고 가정:
- 우리의 눈은 -z를보고 원점에 있습니다.
- 스크린 (평면 근처)은
z = -1
길이 2의 제곱입니다. - 절두체의 먼 평면은
z = -2
더 일반적인 유형의 벡터 4 개만 허용 한 경우 :
(x, y, z, w)
와 w != 0
, 또한 우리는 모든을 식별 (x, y, z, w)
로 (x/w, y/w, z/w, 1)
, 다음 매트릭스와 절두체 변환은 다음과 같습니다
| 1 0 0 0 | | x | | x | | x / -z |
| 0 1 0 0 | * | y | = | y | identified to | y / -z |
| 0 0 1 0 | | z | | z | | -1 |
| 0 0 -1 0 | | w | | -z | | 0 |
우리가 던져 경우 z
와 w
마지막에, 우리는 얻을 :
x_proj = x / -z
y_proj = y / -z
정확히 우리가 원하는 것입니다! 다음과 같은 일부 값의 경우 다음을 확인할 수 있습니다.
- 경우
z == -1
, 정확히 우리가 투영하고있는 비행기x_proj == x
와y_proj == y
. - 경우
z == -2
다음x_proj = x/2
개체는 절반 크기입니다.
glFrustum
변환이 적절한 형식이 아닌 방법에 유의하십시오 . 회전과 변환만으로는 구현할 수 없습니다.
를 더하고 w
나누는 수학적 “속임수”를 동종 좌표 라고 합니다.
참조 : 관련 스택 오버플로 질문 : https : //.com/questions/2465116/understanding-opengl-matrices