Ukázková zkoušková úloha: Geometrické konstrukce

Představte si, že píšete knihu o geometrii a potřebujete do ní přidat obrázky různých geometrických konstrukcí. Protože obrázků potřebujete hodně a nechcete je kreslit ručně, napište program, který je za vás vygeneruje.

Vstup programu je popis geometrické konstrukce (body, přímky, kružnice) a výstupem by měl být obrázek. Pro kreslení použijeme nějakou knihovnu, abychom to nemuseli dělat ručně, například v C# můžeme použít třídu Graphics ze System.Drawing a její metody DrawLine (čára mezi dvěma body), DrawEllipse (kružnice), FillEllipse (bod = vyplněný kruh), …

Příklad výstupu (převzatý z Gergelitsová, Holan: The Golden Ratio Determined Using a Ruler and Compass):

Geometrická konstrukce

Části řešení

  1. upřesnění zadání
  2. postřehy
  3. volba algoritmu
  4. reprezentace dat
  5. dekompozice
  6. diskuze – co šlo dělat jinak

Upřesnění zadání

Geometrická konstrukce je popsaná pomocí následujících operací:

  • bod zadaný pomocí souřadnic (např. point A 0 1),
  • přímka zadaná pomocí dvou bodů (např. line p1 A B),
  • kružnice zadaná pomocí středu a poloměru – poloměr je vzdálenost dvou bodů (např. circle k1 A A B),
  • kružnice zadaná pomocí dvou bodů – střed a bod ležící na kružnici (např. circle k2 B A),
  • bod jako průsečík dvou přímek nebo kružnic (např. point C p1 k2).

Řešení (část)

Rovnice přímky ze dvou bodů

Nechť máme body \[ A = (A_x, A_y),\quad B = (B_x, B_y). \]

  1. Výpočet směrnice: \[ m = \frac{B_y - A_y}{B_x - A_x} \]
  2. Směrnicová rovnice přímky: \[ y= m(x - A_x) + A_y \]
  3. Převod na obecný tvar \((a x + b y + c = 0)\): \[ m x - y + (A_y - m A_x) = 0 \]
  4. Odstranění zlomků násobením \((B_x - A_x)\): \[ (B_y - A_y) x + (- B_x + A_x) y+\bigl(A_y(B_x - A_x)-A_x(B_y-A_y)\bigr)=0 \]
  5. Koeficienty obecné rovnice přímky: \[ a = B_y - A_y,\quad b = A_x - B_x,\quad c = B_x A_y - A_x B_y \]

Rovnice kružnice ze středu a poloměru

Nechť střed kružnice je \( S = (S_x, S_y) \) a poloměr \(r\). Pak platí \[ (x - S_x)^2 + (y - S_y)^2 = r^2 \]

Pokud známe bod \(P=(P_x,P_y)\) na kružnici (místo poloměru), pak \[ r = \sqrt{(P_x - S_x)^2 + (P_y - S_y)^2} \]


Průsečík dvou přímek

Mějme dvě přímky \[ p_1: a_1 x + b_1 y + c_1 = 0, \quad p_2: a_2 x + b_2 y + c_2 = 0 \] Řešíme soustavu lineárních rovnic

  1. Spočítáme determinant \[ D = \begin{vmatrix} a_1 & b_1\\ a_2 & b_2 \end{vmatrix} = a_1 b_2 - a_2 b_1 \] Pokud \(D = 0\), přímky jsou rovnoběžné nebo totožné (tedy nemají jeden průsečík).
  2. Použijeme Cramerovo pravidlo \[ x = \frac{ \begin{vmatrix} -c_1 & b_1\\ -c_2 & b_2 \end{vmatrix} }{D} = \frac{b_1 c_2 - b_2 c_1}{D} \] \[ y = \frac{ \begin{vmatrix} a_1 & -c_1\\ a_2 & -c_2 \end{vmatrix} }{D} = \frac{a_2 c_1 - a_1 c_2}{D} \]

Průsečík kružnice a přímky

Nechť máme kružnici \[ (x - S_x)^2 + (y - S_y)^2 = r^2 \] a přímku \[ a x + b y + c = 0 \]

A) Obecná přímka (nenulové \(b\))
  1. Vyjádříme \(y\) z přímky: \[ y = m x + k, \quad m = -\frac{a}{b}, k = -\frac{c}{b}. \]
  2. Dosadíme do rovnice kružnice: \[ (x - S_x)^2 + (m x + k - S_y)^2 = r^2 \]
  3. Rozepíšeme: \[ x^2 - 2S_x x + S_x^2 + m^2 x^2 + 2m(k - S_y)x + (k - S_y)^2 = r^2. \]
  4. Sestavíme kvadratickou rovnici \[ (1 + m^2)x^2 + (-2S_x + 2m(k - S_y))x + (S_x^2 + (k - S_y)^2 - r^2) = 0 \]
  5. Řešíme standardně pomocí diskriminantu \[ x = \frac{-B \pm \sqrt{B^2 - 4AC}}{2A},\quad y = m x + k \] kde \[ A = 1 + m^2,\quad B = -2S_x + 2m(k - S_y),\quad C = S_x^2 + (k - S_y)^2 - r^2 \]
B) Vertikální přímka \((b=0)\)
  1. Rovnice přímky je: \(x = -\tfrac{c}{a}\)
  2. Dosadíme do rovnice kružnice: \[ \Bigl(-\tfrac{c}{a} - S_x\Bigr)^{2} + (y - S_y)^{2} = r^{2} \]
  3. Upravíme na kvadratickou rovnici: \[ y^2 - (2S_y)y + \Bigl(S_y^2 - r^2 + (-\tfrac{c}{a} - S_x)^2\Bigr) = 0 \]
  4. Řešíme standardně pomocí diskriminantu

Průsečík dvou kružnic

Nechť máme kružnice
\[ (x - S_x)^2 + (y - S_y)^2 = s^2, \quad (x - R_x)^2 + (y - R_y)^2 = r^2 \]

  1. Odečteme druhou rovnici od první \[ (x - S_x)^2 + (y - S_y)^2 \;-\; (x - R_x)^2 - (y - R_y)^2 = s^2 - r^2 \]
  2. Po roznásobení a upravení dostaneme lineární rovnici (kvadratické členy se odečtou): \[ x\,(R_x - S_x) + y\,(R_y - S_y)
    • \frac{s^2 - r^2 + R_x^2 + R_y^2 - S_x^2 - S_y^2}{2} = 0 \]
  3. Tato rovnice představuje přímku. Můžeme tedy spočítat její průsečík s libovolnou z původních kružnic (algoritmem výše) a dostaneme průsečík dvou kružnic.