4x4行列の積の計算方法（言語別）

# はじめに
CG計算における4x4行列の計算。
任意の点を中心に、任意の角度回転させるような、行列Mの計算例について、いくつかの言語で計算。できるだけ、何らかのライブラリを用いて、簡易に書けるように努力。

```math
\begin{bmatrix}
   1 & 0 & 0 & A \\
   0 & 1 & 0 & B \\
   0 & 0 & 1 & 0 \\
   0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
   S & 0 & 0 & 0 \\
   0 & S & 0 & 0 \\
   0 & 0 & S & 0 \\
   0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
   cos & -sin & 0 & 0 \\
   sin & cos & 0 & 0 \\
   0 & 0 & 1 & 0 \\
   0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
   1 & 0 & 0 & -A \\
   0 & 1 & 0 & -B \\
   0 & 0 & 1 & 0 \\
   0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
   x \\
   y \\
   z \\
   1
\end{bmatrix}
=M
\begin{bmatrix}
   x \\
   y \\
   z \\
   1
\end{bmatrix}
=
\begin{bmatrix}
   x' \\
   y' \\
   z' \\
   1
\end{bmatrix}
```

# Pythonで計算
https://paiza.io/projects/xDcx83lTS3vtiJdOYyEI7Q?language=python3

```python
import math
import numpy as np
np.set_printoptions(precision=3,suppress=True)

A = 19
B = 99
th = math.radians(10*30)
sin = math.sin(th)
cos = math.cos(th)
S = 22

a = np.array([[1, 0, 0, A],
              [0, 1, 0, B],
              [0, 0, 1, 0],
              [0, 0, 0, 1]])
s = np.array([[S, 0, 0, 0],
              [0, S, 0, 0],
              [0, 0, S, 0],
              [0, 0, 0, 1]])
r = np.array([[cos, -sin, 0, 0],
              [sin, cos, 0, 0],
              [0, 0, 1, 0],
              [0, 0, 0, 1]])
b = np.array([[1, 0, 0, -A],
              [0, 1, 0, -B],
              [0, 0, 1, 0],
              [0, 0, 0, 1]])

print(np.dot(np.dot(np.dot(a, s),r),b))
```

```
[[   11.       19.053     0.    -2076.203]
 [  -19.053    11.        0.     -628.001]
 [    0.        0.       22.        0.   ]
 [    0.        0.        0.        1.   ]]
```

# Processingで計算
PMatrix3Dクラスを使う。
直接値を代入しても良かったが、関数が用意されていたので利用した。

https://processing.github.io/processing-javadocs/core/processing/core/PMatrix3D.html


```java
float A = 19f;
float B = 99f;
float th= 10*30*PI/180f;
float S = 22f;

PMatrix3D a = new PMatrix3D();
PMatrix3D s = new PMatrix3D();
PMatrix3D r = new PMatrix3D();
PMatrix3D b = new PMatrix3D();

a.set(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
  );
s.set(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
  );
r.set(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
  );
b.set(
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1
  );
a.translate(A, B, 0);
s.scale(S);
r.rotateZ(th);
b.translate(-A, -B, 0);

a.apply(s);
a.apply(r);
a.apply(b);
a.print();
```

```
 0011.0000  0019.0526  0000.0000 -2076.2031
-0019.0526  0011.0000  0000.0000 -0628.0022
 0000.0000  0000.0000  0022.0000  0000.0000
 0000.0000  0000.0000  0000.0000  0001.0000
```


# wolfram Alphaで計算
文字数制限があったので、途中の計算まで
```
{{1,0,0,A},{0,1,0,B},{0,0,1,0},{0,0,0,1}} . {{S,0,0,0},{0,S,0,0},{0,0,S,0},{0,0,0,1}} . {{1,0,0,-A},{0,1,0,-B},{0,0,1,0},{0,0,0,1}},A=19,B=99,S=22
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/a229d354-3666-7d82-53f5-5c63f95bb4b3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/ec31abad-5988-b098-8b53-b9002ed643f4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/c907538b-ae36-c1e3-8911-548e042a672d.png)

# エクセルで計算
MMULT関数を使えば一発！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/50e9b7eb-7323-5f5d-ca4c-3179219253de.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/f358c3fc-49ac-3c4c-dcb4-b45058d835fb.png)

# Webで計算
https://keisan.casio.jp/exec/system/1308269580

# MicrosoftのMathアプリ
文字認識がうまく行かず。
手書きでやる？