Aplikace maticového počtu v geometrii#

Pomocí matic dokážeme efektivně popsat transformaci roviny nebo projekci prostoru do roviny. Ukážeme si toto využití matic na jednoduchých příkladech. Ukážeme si i triky, jak obejít omezení plynoucí z vlastností násobení, a to že počátek se zobrazuje na počátek a rovnoběžky se zobrazují na rovnoběžky. Ukážeme si, že zavedením homogenních souřadnic je možné do repertoáru transformací vyjádřitelných maticemi je možno započítat i posunutí a perspektivu.

import numpy as np
np.set_printoptions(precision=3, suppress=True)
from numpy import sqrt, sin, cos, pi
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
vzory=np.array([[0,0],[2,0],[2,1],[1,1.6],[0,1],[0,0]]).T
plt.plot(*vzory)
plt.gca().set_aspect('equal')
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[1], line 1
----> 1 import numpy as np
      2 np.set_printoptions(precision=3, suppress=True)
      3 from numpy import sqrt, sin, cos, pi

ModuleNotFoundError: No module named 'numpy'

Transformace roviny#

Kartézské souřadnice#

Modrý domeček postupně zobrazujeme různými maticemi.

A=np.array([[2,0],[0,2]])
B=np.array([[1,0.5],[0,0.6]])
theta=pi/3
P=np.array([[cos(theta)**2,sin(theta)*cos(theta)],[sin(theta)*cos(theta),sin(theta)**2]]) # projekce
R=np.array([[cos(theta),-sin(theta)],[sin(theta),cos(theta)]]) # rotace

def transformuj(M, vzory=vzory):
    obrazy = M @ vzory
    fig,ax = plt.subplots()
    poly = Polygon(vzory.T, facecolor='C0', alpha=0.5)
    ax.add_patch(poly)
    poly = Polygon(obrazy.T, facecolor='C1', alpha=0.5)
    ax.add_patch(poly)
    ax.plot(*vzory, *obrazy)
    ax.set(title=M)
    ax.set_aspect('equal')
    ax.grid()

for M in [A,B,P,R,R@P,P@R]:
    transformuj(M)
    
../_images/75e07d536d0da5ee8cf5501ff979db06a911add172f3b2613062abffccb439fa.png ../_images/1f81adad113f83bf578b3235520b2cb33db94ffd7bc96876367a0419058351e5.png ../_images/a56c01dea19a12c0dd0e3b0ac68956693e3a0d51d2ebcf7c77e3445a3cc8a050.png ../_images/13898942d83bb596dd7d1f132170eea7e301dcf96b265309b8fa56087aa432d4.png ../_images/8ae23a4088dabe3d577b5680ce9535037a6577e271eeda482aac295b471f4a5d.png ../_images/9303327f1895b71675e47ac88545f3832d5f9b1fd0c7acf498177d27a076ed7d.png

Homogenní souřadnice#

Homogenní souřadnice umožňují i posunutí. Neplatí zde, že počátek se nutně zobrazuje na počátek.

vzory_h = np.zeros((vzory.shape[0] + 1, vzory.shape[1]))
vzory_h[:2,:] = vzory
vzory_h[2,:] = 1
print("Obrázek v homogenních souřadnicích: \n",vzory_h)
M = np.array([1,0,3,0,1,1]).reshape((2,3))
obrazy = M @ vzory_h
fig,ax = plt.subplots()
poly = Polygon(vzory.T, facecolor='C0', alpha=0.5)
ax.add_patch(poly)
poly = Polygon(obrazy.T, facecolor='C1', alpha=0.5)
ax.add_patch(poly)
ax.plot(*vzory, *obrazy)
ax.set(title=M)
ax.set_aspect('equal')
ax.grid()
Obrázek v homogenních souřadnicích: 
 [[0.  2.  2.  1.  0.  0. ]
 [0.  0.  1.  1.6 1.  0. ]
 [1.  1.  1.  1.  1.  1. ]]
../_images/9df3a0822a3f110c6d5c2d6ac85b40986c960a6ce0c2a2402f6945ca1f53eca6.png

Transformace prostoru do roviny#

Afinní transformace#

vzory3d = np.zeros((3,12))
vzory3d[:2,:] = np.tile(vzory,2)
vzory3d[2,6:] = 1.7
vzory3d
array([[0. , 2. , 2. , 1. , 0. , 0. , 0. , 2. , 2. , 1. , 0. , 0. ],
       [0. , 0. , 1. , 1.6, 1. , 0. , 0. , 0. , 1. , 1.6, 1. , 0. ],
       [0. , 0. , 0. , 0. , 0. , 0. , 1.7, 1.7, 1.7, 1.7, 1.7, 1.7]])
Matice=[
    np.array([[1,0,0],[0,1,0]]), 
    np.array([[1,0,0.5],[0,1,.5]]), 
    np.array([[0,0,1],[0,1,0]]), 
    np.array([[0.5,0,.6],[-.2,1,.8]]), 
]

for A in Matice:
    projekce = A @ vzory3d
    fig, ax = plt.subplots()
    plt.plot(*projekce,"C0")
    for i in range(5):
        plt.plot(projekce[0,i::6], projekce[1,i::6], 'C0')
        ax.set(title=A)
        ax.grid()
../_images/3c6544d684b596865c0e6da7155bdca4616072928e6b0d1bd5f7dcc3d6c5116b.png ../_images/6d18c57ddacaf886670f33ba4af12c8348e5b7b5d673bab6777208b13ab7134f.png ../_images/fe6688f6a24b839be27b6fb1b573f21dcfbd805f85a0018808c0c6653630c4f8.png ../_images/824f090b54acc3641390f584f590644c9c8bdad3b0a2e17cfe2fd57a0b3f6bc3.png

Perspektiva#

Viz Wikipedie

f=5
v = vzory3d + np.array([[-3,-2,5]]).T # posun obrazku mimo pocatek soustavy souřadnic

M = np.diag([1,1,1/f]) # projekcni matice
o = M @ v # aplikace matice
o = o / o[2,:] # prevod z homogennich souradnic na kartezske

fig, ax = plt.subplots()
ax.plot(*o[:2,:],"C0")
for i in range(5):
    ax.plot(o[0,i::6], o[1,i::6], 'C0')
ax.set(title=M)
ax.grid();
../_images/944f10f9777d49cdb270cb7411ba259716c50706fd955549ee66f5baf8f3d551.png