# CAMA : Exercices
# Exercice 1.1
Écrire sous forme d'un produit matriciel la symétrie axiale par rapport à un axe qui ne passe pas par (0,0). On prendra l'axe qui passe par (2,0) et qui a un angle de π/3 par rapport à l'horizontale.
Est-ce un automorphisme orthogonal ? Le montrer.
:::spoiler Solution
```python=
def R3(α):
return np.array([[np.cos(α), -np.sin(α), 0], [np.sin(α), np.cos(α), 0], [0, 0, 1]])
Sx3 = np.array([[1,0,0], [0,-1,0], [0,0,1]])
def T(v): # translation of v
T = np.identity(3)
T[0:2,2] = v
return T
θ = np.pi / 3
a = np.array([2,0])
S = T(a) @ R3(θ) @ Sx3 @ R3(-θ) @ T(-a)
print("Matrix of symmetry:\n", S)
shape2 = S @ shape1_3d
plt.plot(shape1[0], shape1[1], ":")
plt.plot(shape2[0], shape2[1])
plt.plot([a[0]-3*np.cos(θ),a[0]+np.cos(θ)],[a[1]-3*np.sin(θ),a[1]+np.sin(θ)], "-.") # axe de symétrie
plt.axis('equal');
```
```
Matrix of symmetry:
[[-0.5 0.866 3. ]
[ 0.866 0.5 -1.732]
[ 0. 0. 1. ]]
```
![](https://i.imgur.com/r0OKNQK.png)
```python=
# Ce n'est pas un automorphisme orthogonal car S n'est pas orthogonale :
S @ S.T
```
```
array([[10. , -5.196, 3. ],
[-5.196, 4. , -1.732],
[ 3. , -1.732, 1. ]])
```
:::
# Exercice 3.1 (rotation de la caméra autour de son axe)
On a indiqué que 𝜃 est l'angle que la caméra fait par rapport à l'horizontal (à supposer que dans le monde réel un des axes est la verticale). Ajouter à toutes les transformations la possibilité de faire tourner la caméra sur son axe principal.
:::spoiler Solution
```python=
# on fait une simple matrice de rotation autour de z après être dans le repère de la caméra
roll = lambda t: np.array([[np.cos(t), -np.sin(t), 0, 0], [np.sin(t), np.cos(t), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
```
```python=
view(F(2.3) @ roll(np.pi/4) @ R @ T(c))
```
![](https://i.imgur.com/iZriqMu.png)
:::
# Exercice 3.2
Définir la direction dans laquelle regarde la caméra avec un vecteur et non 2 angles de rotation. Rédigez pour expliquer vos calculs.
```python=
direction = [1,1,0] # à gauche à 45 degré
```
:::spoiler Solution
On a vu que dans la monde 3D réel la direction initiale de la caméra est x.
Il faut transformer la nouvelle direction qu'on nous donne pour la caméra en 2 angles de rotation ce qui donnera nos 2 matrices de rotation. On calcule les angles en fonction de la direction donnée grace aux formules de trigonométrie qu'on retrouve sur le cercle unité.
En 2D on a :
* $x=\cos(\alpha)$
* $y=\sin(\alpha)$
Donc si on a la direction (x,y) cela veut dire que l'angle qui nous intéresse est $\alpha=\arccos(x)$ mais ATTENTION cela n'est juste que si la direction est de norme = 1. Aussi on prend le ratio entre x et y qui est égale au ratio des valeurs normées. Ainsi
$$
\alpha=\arctan(y/x)
$$
En 3D on doit se rapportee au cas 2D qui différe suivant qu'on cherche l'angle vertical ou horizontal.
La rotation horizontale se fait dans le plan [x,y] :
* $x=\cos(\psi)$
* $y=\sin(\psi)$
et donc
$$
\psi=\arctan(y/x)
$$
La rotation verticale se fait dans le plan [x+y, z] avec $\psi\in[−\pi/2,\pi/2]$
* $||x+y||=cos(\phi)$
* $z=\sin(\phi)$
et donc
$$
\phi=\arctan(z/||x+y||)
$$
```python=
def D(direction):
if len(direction) == 2: # 2 angles
ah = direction[0]
av = direction[1]
else: # on convertit la direction en angle
norm = np.sqrt(direction[0]**2 + direction[1]**2)
if norm == 0: # alors c'est vertical
ah = 0
av = 1
else:
av = np.arctan(direction[2]/norm)
if direction[0] == 0:
if direction[1] != 0:
ah = np.sign(direction[1]) * np.pi/2
else:
ah = np.arctan(direction[1]/direction[0])
print(ah, av)
if type(ah) == int:
ah = ah * 2 * np.pi / 360
av = av * 2 * np.pi / 360
rh = np.array([[np.cos(ah), -np.sin(ah), 0, 0], [np.sin(ah), np.cos(ah), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
rv = np.array([[np.cos(av), 0, np.sin(av), 0], [0, 1, 0, 0], [-np.sin(av), 0, np.cos(av), 0], [0, 0, 0, 1]])
return rv @ rh
```
```python=
view(F(2.3) @ R @ D([1,1,0]) @ T(c))
```
```
0.7853981633974483 0.0
```
![](https://i.imgur.com/lR8yMWH.png)
:::