É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.
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. ]]
# 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. ]])
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.
# 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]])
view(F(2.3) @ roll(np.pi/4) @ R @ T(c))
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.
direction = [1,1,0] # à gauche à 45 degré
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 :
Donc si on a la direction (x,y) cela veut dire que l'angle qui nous intéresse est
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] :
et donc
La rotation verticale se fait dans le plan [x+y, z] avec
et donc
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
view(F(2.3) @ R @ D([1,1,0]) @ T(c))
0.7853981633974483 0.0