Znamenite točke trikotnika

Znamenite točke trikotnika

Avtor: Anonimen

Besedilo naloge in pristop

(besedilo.jpg)

Pristop k reševanju

Problem lahko razdelim na dve ključni nalogi:

  • izračun vseh znamenitih točk trikotnika
  • izris trikotnika in točk

Izračun znamenitih točk

Poiskati moram enostaven a stabilen način izračuna:

  • višinske točke
  • središča trikotniku očrtanega kroga
  • središča trikotniku včrtanega kroga
  • težišče

Izris trikotnika in točk

Tu je največji problem spreminjanje velikosti okna. Če uporabnik okno lepo sorazmerno povečuje se točke izračunajo kar iz relativnih koordinat. Problem nastane če uporabnik okno raztegne le v eni smeri. V tem primeru se trikotnik močno deformira in znamenite točke je potrebno ponovno izračunati. Sicer lahko uporabnik dobi napačno predstavo o njih.

Težišče trikotnika

Najprej bom opisal izračun vseh znamenitih točk, saj je to jedro programa. Izračun težišča je daleč najlažja operacija, tako da bom najprej opisal ta izračun.

Težišče na wikipediji

Po ogledu zgornje povezave izvem, da se težišče trikotnika izračuna kot povprečje koordinat vseh treh oglišč. Pristop v C# je enostaven:

(tezisce.jpg)

Naj še predstavim objekt tipa Point(x,y). To je objekt, ki predstavlja točko s celimi koordinatami x in y. V nadaljevanju bom pokazal, še več uporabe tega razreda.

Višinska točka

Višinska točka na wikipediji

Zopet se za nasvet o izračunu zatečem na Wikipedijo. Tu najdem več možnih pristopov k računanju. Izberem slednjega:

(visinska_wiki.jpg)

Sestavek pravi, da če je a dolžina stranice med ogliščema B in C, b dolžina AC ter c dolžina AB lahko višinsko točko izračunam v Baricentričnih koordinatah po zgornji formuli.

Za osvežitev spomina naj povem, da baricentrične koordinate podajajo oddaljenosti od oglišč trikotnika. Točka podana z njimi je tako enlično določena.

Izračun v C# izgleda tako:

(visinska_tocka.jpg)

Koda je enostanva:

  • najprej izračunam dolžine stranic in jih shranim v spremenljivke da, db in dc
  • v skladu z zgornjo formulo izračunam baricentrične koordinate b1, b2 in b3
  • izračunam kartezični koordinati točke Px in Py

Ker sem enak pristop uporabil tudi pri ostalih točkah, bom več o sami strukturi funkcije povedal na naslednji prosojnici.

Središče trikotniku včrtanega kroga

Včrtan krog na Wikipediji

V članku piše, da je središče trikotniku včrtanega kroga enolično podano z baricentričnimi koordinatami a:b:c pri čemer so a,b in c dolžine stranic.

Pristop v C# bo enak prej opisanemu:

(sredisce_vcrtanega.jpg)

Funkcija, ki točko računa je tipa bool. Vrača le vrednosti true in false. A zakaj?

Pri pretvorbi iz baricentričnih v kartezične koordinate je podrebno deljenje s spremenljivko s, ki je obseg trikotnika. Če vsa tri oglišča ležijo na isti točki, bo s seveda 0. Pri deljenju z nič pa kaj hitro dobim Overflow Error, ki me opozarja na nedovoljeno deljenje z 0. Zato najprej preverim če je s == 0. V tem primeru vrnem false, ki pomeni, da točke ne morem izračunati. Če pa s ni enak 0 lahko točko izračunam ter jo vrnem v obliko out Point T.

Središče trikotniku očrtanega kroga

Očrtan krog na Wikipediji

Pri izračunu središča trikotniku očrtanega kroga sem uporabil nekoiliko drugačen pristop. Namesto uporabe baricentričnih koordinat sem izračunal kar kartezične neposredno:

(ocrtan_wiki.jpg)

Tudi tu pa imam deljenje z nekim številom D, tako da bom moral preveriti da D slučajno ni enak 0.

Zgornja formula in preverjanje deljenja z 0 v C# izgleda tako:

(sredisce_ocrtanega.jpg)

Pomožni razred Tocka

Do sedaj sem pokazal kako iz treh točk izračunam znamenite točke trikotnika. Oglišča trikotnika v tem primeru podam v obliki Point(x,y) kjer sta x in y koordinate oglišča številskega tipa int. To je zelo uporabno pri risanju, kot bom pokazal v kratkem. Problem nastane pri tako imenovanem resize - spremembi velikosti platna. Tako kot se poveča platno se mora povečati tudi trikotnik. Če se trikotnik pri povečevaju spremeni pa se morajo ponovno izračunati tudi znamenite točke, sicer dobi uporabnik napačno predstavo.

Za rešitev zgoraj opisanih problemov sem uporabil naslednji pristop:

  • Definiram objekt Točka(x iz [0,1],y iz [0,1]), ki predstavlja relativno pozicijo oglišča
  • Pozicijo oglišča na platnu izračunam s pretvorbo Točka(x,y) v Point(x,y).
  • Izračunam znamenite točke

Sestavil sem torej razred Tocka za delo z objekti tipa tocka:

(spremenljivke_tocka.jpg)

V ta razred sem vključil tudi prej opisane statične metode za izračun znamenitih točk. Razredu sem dodal še metodo toPoint, ki skrbi za pretvorbo iz Tocka(x,y) v Point(x,y):

(toPoint.jpg)

Forma

Forma je sestavljena iz treh elemento:

  • glavna forma z imenov glavnaForma
  • plošča z imenom panel1
  • gumb z imenom button1
(forma.jpg)

Ob pritisku na gumb se na plošči pojavi naključni trikotnik z narisanimi znamenitimi točkami. Ob spremembi velikosti glavne forme, se trikotnik spreminja v skladu z dolžinami stranic plošče. Plošča je 'priklenjena' na glavno formo na vseh štirih stranicah. Gumb je 'priklenjen' le na levem in spodnjem koncu.

Spremenljivke glavnega programa

Glavni program se začne z deklaracijo spremenljivk. a,b in c so objekti tipa Točka. V njih bodo shranjene relativne koordinate x in y ogljišč trikotnika.

Vse ostale spremenljivke so tipa Point, v njih so shranjene absolutne koordinate točk.

Imam tudi objekt Pen crta, ki je pisalo rdeče barve ter Brush polilo, ki bo barval točke z modro barvo.

(spremenljivke.jpg)

Load in klik na gumb

Pri tako imenovanem 'Event driven programming' je nekoliko komplicirano opisati delovanje programa, saj si klici metod ne sledijo po nekem vrstnem redu kot pri algoritmih.

Zato bom opisal delovanje vsake metode in povedal kateri dogodek jo sproži.

Load

Ob zagono forme se proži metoda load_main_form, ki najprej simulira klik na gumb. Tako se sproži metoda nove_tocke opisana v nadaljevanju. Metoda load tudi prebere višino in širino plošče panel1 ter vrednosti shrani v Point(širina plošče, višina plošče). Te vrednosti bom kmalu potreboval.

(load.jpg)

Pritisk na gumb

Ob pritisku na gumb se sproži metoda nove_tocke. Ta objektom tipa Tocka(x,y) nastavi nove vrednosti za x in y. Tako se Ustvari nov komplet treh oglisšč, katera imajo nove koordinate. Njihova vrednost je med 0 in 1.

(nove_tocke.jpg)

Na koncu s klicem panel1.Invalidate() se sproži še risanje na ploščo.

Izračunaj točke

Metoda izracunaj_tocke vzame vsa tri oglišča v absolutnih koordinatah ter izračuna znamenite točke trikotnika.

(izracunaj_tocke.jpg)

Pri računanju ji pomagajo prej opisane metode, ki preverjajo, če lahko točko izračunam. Naj spomnim da so metode sredisce_vcrtanega, sredisce_ocrtanega in visinska_tocka metode, ki vračajo vrednosti false in true, samo točko pa kot out parameter.

Če lahko vse tri točke izračunam; metode vrnejo true, potem izračunam še težišče.

V malo verjetnem primeru, da so vsa tri ogljišča na isti točki, potem ustvarim nova ogljišča.

Risanje

Metodda paint se sproži ob ob klicu panel1.Invalidate() ter ob ustvarjenju plošče panel1. To je tista metoda, ki na ploščo riše, torej najpogosteje deluje.

Metoda paint najprej nariše trikotnik kot črto med točkami A,B,C in A s pomočjo Graphics.DrawLine.

Nato se znotraj metode sproži metoda izracunaj_Tocke, ki izračuna vrednosti znamenitih točk.

(paint.jpg)

Na koncu nariše znamenite točke kot elipse s pomočjo Graphics.FillElipse.

Sprememba velikosti

Ob spremembi velikosti glavne forme, se sproži metoda resize.

Ta nastavi novi vrednosti širine in višine plošče panel1. Nato pokliče risanje. Ker se pri risanju oglišča ponovno izračunajo iz relativnih koordinat je nov trikotnik primerne velikosti.

(resize.jpg)

Ponovno računanje zagotavlja pravilno vrednost znamenitih točk.

Primeri uporabe

Do sedaj sem opisal metode potrebne za izgradnjo programa. Ko program zaženem se pojavi okno s trikotnikom in znamenitimi točkami. Ob vsakem kliku se pojavi nov trikotnik in pripadajoče točke. Ob spremembi velikosti se trikotnik sorazmerno povečuje in zmanšuje. Točke v skladu s trikotnikom spreminjajo lego.

Spodaj je nekaj primerov uporabe:

0%
0%