Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Lekce 06

V následující lekci budeme s využití poznatků z minulých lekcí řešit různé problémy.

Obsah kružnice

V této podkapitole si ukážeme různé způsoby výpočtu obsahu kružnice.

Výpočet obsahu jednotkové kružnice pomocí poznatků z minulé lekce

Použijeme kód pro aproximaci plochy pod křivkou, kterou jsme si ukázali na minulé hodině. Největší problém je nalezení samotné funkce, jejiž plochu budeme počítat.

Vyjdeme z rovnice pro jednotkovou kružnici:

x2+y2=1x^2+y^2=1

A vyjádříme si z ní yy:

y2=1x2y^2=1-x^2

y=1x2y=\sqrt{1-x^2}

Toto vložíme do skriptu, který známe z minulé hodiny. Ale pozor - budeme plochu počítat pouze na intervalu <0,1><0, 1>, takže výsledek bude odpovídat jedné čtvrtině výsledné plochy. Proto je nakonci plocha vynásobena 4. Výsledek musí odpovídat hodnotě π\pi, proto si ji vypíšeme, ať můžeme výsledky porovnat.

n=20


funkce=@(x) sqrt(1-x.^2);


x=linspace(0,1,n);

delta=x(2)-x(1);

plocha=0;

for i=1:1:n-1
    plocha=plocha+delta*abs(funkce(x(i)+delta/2));
end

plocha=plocha*4
pi
n = 20
plocha = 3.145736799792407
ans = 3.141592653589793

Modifikace 1 - kružnice o poloměru rr

Upravíme program tak, aby počítal obsah kruhu o poloměru rr.

Budeme muset upravit samotnou funkci tak, aby reflektovala zadaný poloměr. Výjdeme tedy ze vzorce

x2+y2=r2x^2+y^2=r^2

A opět si vyjádříme yy:

y2=r2x2y^2=r^2-x^2

y=r2x2y=\sqrt{r^2-x^2}

n=2000
r=7

format long
funkce=@(x) sqrt(r.^2-x.^2)


x=linspace(0,r,n);

delta=x(2)-x(1)

plocha=0

for i=1:1:n-1
    plocha=plocha+delta*abs(funkce(x(i)+delta/2));
end

4*plocha

pi*7^2
n = 2000
r = 7
funkce =

@(x) sqrt (r .^ 2 - x .^ 2)

delta = 3.501750875437719e-03
plocha = 0
ans = 153.9382288564295
ans = 153.9380400258999

Modifikace 2 - obsah kruhu pomocí obsahu pravidelného vepsaného N-úhelníku

Uprav program tak, ať počítá obsah kruhu pomocí obsahu vepsaného pravidelného N-úhelníku.

Tady je potřeba si vše rozkleslit.

Takto by vypadal náš kruh, pokud bychom do něj vepsali 8

octave

Tento n-uhelník je tvořen 8 stejnými rovnoramennými trojúhelníky

octave

Zaměříme se tedy na jeden z trojúhelníků (pak jen výslednou plochu budeme muset vynásobit 8 - tedy N).

octave

A využijeme následující větu pro obsah trojúhelníku

S=12absin(γ)S=\frac{1}{2}\cdot a\cdot b\cdot \sin(\gamma), kde aa a bb budou rovny poloměru rr a úhel γ\gamma bude úhel při ramenech. Velikost úhlu zjistíme jako 2πN\frac{2\cdot\pi}{N}.

N=8000
r=1

uhel=2*pi/N

S=1/2*r^2*sin(uhel)

vysledek=S*N
N = 8000
r = 1
uhel = 7.853981633974483e-04
S = 3.926990413259693e-04
vysledek = 3.141592330607755

Co bychom ale dělali v situaci, kdy neznáme výše uvedený vzorec?

V takovém případě bychom vyšli z toho co víme o pravoúhlém trojúhelníku.

octave

Abychom zjistili plochu horního trojúhelníku, stačí zjistit hodnoty aa a bb:

sin(γ)=ara=rsin(γ)\sin(\gamma)=\frac{a}{r} \Rightarrow a=r \sin(\gamma)

cos(γ)=brb=rcos(γ)\cos(\gamma)=\frac{b}{r} \Rightarrow b=r \cos(\gamma)

a z toho nám plyne, že pro obsah celého trojúhelníku platí (plochu není třeba dělit 2, protože jsme rovnou spočítali plochou obou pravoúhlých trojúhelníků)

S=rrsin(γ)cos(γ)S=r\cdot r\cdot sin(\gamma)\cdot\cos(\gamma)

Musíme ovšem myslet na to, že použitý úhel je poloviční než v předchozím příkladu, tj. 2π2N=πN\frac{2\cdot\pi}{2\cdot N}=\frac{\pi}{N}

%počet dělení
N = 1000000
r=1

uhel=pi/N

obsah=r*r*sin(uhel)*cos(uhel)

obsah=obsah*N
N = 1000000
r = 1
uhel = 3.141592653589793e-06
obsah = 3.141592653569122e-06
obsah = 3.141592653569123

Modifikace 3 - obsah kruhu pomocí obsahu pravidelného opsaného N-úhelníku

Uprav program tak, ať počítá obsah kruhu pomocí obsahu opsaného pravidelného N-úhelníku. Tentokrát ponechám výpočet na čtenářích. Výsledný kód je následující (na Vás je přijít na to proč).

%počet dělení
N = 1000000
r=1

uhel=pi/N

obsah=r^2*tan(uhel)

obsah=obsah*N
N = 1000000
r = 1
uhel = 3.1416e-06
obsah = 3.1416e-06
obsah = 3.1416

Modifikace 4 - využijeme oba předchozí postupy

V následujícím příkladu spojíme oba předchozí příklady s využitím while.

Pro zvolené NN vždy spočítáme patřičný úhel a obsahy vnitřního a i vnějšího N-úhelníků. Pokud bude rozdíl obsahů menší než předem stanovená hranice (0.00001), zvýšíme NN o 1 a provedeme výpočet znovu. Takto budeme výpočet opakovat tak dlouho, dokud nebude rozdíl obou obsahů dostatečně malý (dosáhneme požadované přesnosti). Na závěr vypočítáme průměrný obsah z obou hodnot.


r=1

rozdil = 1

N=4

while rozdil > 0.00001
    
    uhel=pi/N;
    obsah_D=N*r*r*sin(uhel)*cos(uhel);
    obsah_H=N*r^2*tan(uhel);
    rozdil=obsah_H-obsah_D;
    N=N+1;
end

N-1
obsah=(obsah_H+obsah_D)/2



r = 1
rozdil = 1
N = 2
ans = 1761
obsah = 3.141590987192505

Dělitelé

Vypiš dělitele zadaného přirozeného čísla n>1n>1.

Abychom určili, zda nějaké číslo dělí číslo nn, potřebujeme funkci modulo. Ta se zadává jako mod() a funguje tak, že po zadaní mod(a,b) nám vrátí celočíselný zbytek po dělení čísla aa číslem bb. Tj. mod(13,5) vrátí 3.

%zadane cislo, jehoz delitele budeme hledat
n=100

%pouzijeme cyklus for, ktery bude hledat delitele pro vsechna cisla od 1 do n
for i=1:1:n
    %funkce if kontroluje, zda je zbytek po celociselnem deleni cisla n cislem i roven nule
    if mod(n,i)==0
        %pokud je splnena podminka, vypise se cislo i (tj. delitel cisla n)
        i
    end
end
n = 100
ans = 3
i = 1
i = 2
i = 4
i = 5
i = 10
i = 20
i = 25
i = 50
i = 100

Nyní kód upravíme tak, že výstup uložíme do jednoho vektoru. Protože nevíme jak bude výsledný vektor veliký, vytvoříme nejprve prázdný vektor (vektor=[]), který budeme následně rozšiřovat o nové dělitele.

%zadane cislo, jehoz delitele budeme hledat
n=100

%prazdny vektor
vektor=[]

%pouzijeme cyklus for, ktery bude hledat delitele pro vsechna cisla od 1 do n
for i=1:1:n
    %funkce if kontroluje, zda je zbytek po celociselnem deleni cisla n cislem i roven nule
    if mod(n,i)==0
        %pokud je splnena podminka, rozsiri se nas novy vektor o prvek i, ktery se zapise nakonec vektoru
        vektor=[vektor i];
    end
end

vektor
n = 100
vektor = [](0x0)
vektor =

     1     2     4     5    10    20    25    50   100

Prvočíslo

Rozhodni, zda je zadané číslo nn prvočíslo.

Pro výpočet použijeme předchozí kód, tj. najdeme všechny dělitele čísla nn a uložíéme je do vektoru vektor. Následně zjistíme velikost vektoru a ověříme, že je velikost rovna 2 (pokud je číslo nn prvočíslo, je dělitelné pouze samo sebou nebo jedničkou, takže má dva dělitele).

%zacatek je stejny jako v predchozim priklade
n=100
vektor=[]

for i=1:1:n
    if mod(n,i)==0
        vektor=[vektor i];
    end
end



%overime, ze je velikost vektoru rovna dvema 
%funkce size urci velikost vektoru, druhy parametr funkce je roven 2 coz funkci rika, ze nas zajima pouze pocet radku - bez tohoto parametru by funkce vratila pocet radku i sloupcu)
if size(vektor,2)==2
    
    display('Hura - jedna se o prvocislo')
    else
    %pokud se nejedna o prvocislo, program nas na to upozorni
    display('Smula, nejedna se o prvocislo')
    %a vypocita pocet delitelu krome 1 a n
    size(vektor,2)-2
end
n = 100
vektor = [](0x0)
Smula, nejedna se o prvocislo
ans = 7

Zde je úprava, která výrazně zrychlý výpočet - dokážete určit, co přesně dělá úprava v cyklu for a proč je takto navržena?

n=126
vektor=[];

for i=3:2:ceil(sqrt(n))
    if mod(n,i)==0
        vektor=[vektor i];
    end
end

if size(vektor,2)==2
    display('Hura - jedna se o prvocislo')
    else
    display('Smula, nejedna se o prvocislo')
end
n = 126
Smula, nejedna se o prvocislo