Lien de la note Hackmd
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.
Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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');
1
2
3
4
Matrix of symmetry:
[[-0.5 0.866 3. ]
[ 0.866 0.5 -1.732]
[ 0. 0. 1. ]]
1
2
3
# Ce n'est pas un automorphisme orthogonal car S n'est pas orthogonale :
S @ S.T
1
2
3
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.
Solution
1
2
3
# 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]])
1
view(F(2.3) @ roll(np.pi/4) @ R @ T(c))
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.
1
direction = [1,1,0] # à gauche à 45 degré
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||)\)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
1
view(F(2.3) @ R @ D([1,1,0]) @ T(c))
1
0.7853981633974483 0.0