# 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) :::