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')
../_images/233598de57503e89ba2d474056bdbbe1198f6aa40f45eaf290a4332b803ed515.png

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/8230be302535ba37662c5d130d98018c0356da5510288e626e33fe25d4247eb9.png ../_images/97caeb18819ba75c7431c9af34993b4bb3cdc681e6f6c4ee8ff0bfd37edfbb0b.png ../_images/789ef51d3a78a0ceb20ea2565bd50a67c2a26a8fec43984dc5669b42eee58465.png ../_images/aa7db0205e50b051c67e295fd057bed75004917a992a3c4854ce070e53ddd7d3.png ../_images/da3ad8263de0311b3cb77f2f87c30a6b237cf726d4beff386faae05a08486aba.png ../_images/78daaee683745eafc30f67340de57f47db9215c4b8a17404b9e232da4ec178d4.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/0df68658e5e2b35544f6e54fda4a8dbf53d5e65755d744e9aef3642e1b856743.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/6632be62278589040cb4efe0a7a962e37cfd4912651f2cc41e1ba9af5996142b.png ../_images/31fe582db9b66fc07d7b90fbde567fe34960e497725a573c4e341c044fa76bf6.png ../_images/e49707ca6f15fa19d48d26f91aefe32bc0fb830bacb3aedbd971e97e83c9c065.png ../_images/bbacd5a497528c246fcb6a432d2ef38bc094d74b34045d68e316ed421c5670c0.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/6d9beec1bdec5619f1c44cd19536dcd10cf10d17b434a78f1ec27eea35ab2ffb.png