Sierpinski (resitev)

Iz R2Wiki
Skoči na: navigacija, iskanje

Tudi tu se srečujemo z objektnim programiranjem, predvsem pa z dedovanjem.


Kratka razlaga dedovanja:

  • Pogosto imajo razredi objektov podobne, vendar ne identične, atribute in operacije. V teh primerih je koristno uporabiti možnost dedovanja lastnosti. Podrazredi (subclasses) podedujejo operacije in atribute nadrazreda (superclass). Seveda lahko podrazred predefinira poljubno metodo in atribut, ki ga (jo) podeduje, definira pa lahko tudi dodatne - svoje lastne operacije in atribute.
  • Dedovanje (inheritance) zagotavlja mehanizem za upravljanje razredov in organiziranje razredne hierarhije, kjer so splošni razredi višje in specializirani nižje v hierarhiji. Ločimo enkratno in večkratno dedovanje. Slednje pogosto vodi k ponavljajočemu dedovanju. Tako enkratno kot večkratno dedovanje pa lahko izkazujeta selektivno dedovanje.
  • Enkratno dedovanje (single inheritance) zasledimo, kadar nek podrazred podeduje značilnosti le od enega nadrazreda. Večkratno dedovanje (multiple inheritance) omogoča, da razred podeduje od večih nadrazredov. Razredna hierarhija dedovanja se zaplete tudi pri ponavljajočem (repeated) dedovanju. Pojavi se v razredu potomcu, ki deduje od dveh staršev, potomcev istega prednika. Selektivno (selective) dedovanje pa zasledimo, kadar podrazred podeduje le nekatere operacije svojega nadrazreda. Ta oblika dedovanja je uporabna v primerih, ko želimo omejiti obseg informacij, do katerih lahko uporabnik dostopa.

Naloga od nas zahteva, da narišemo eno od rekurzivnih krivulj ali likov. Odločili smo se za Sierpinski trikotnik. Sierpinski trikotnik je fraktal v obliki trikotnika v katerem manjkajo večji in manjši trikotnik.


Slika Sierpinskega trikotnika tretjega reda.

Trikotnik Sierpinskega.jpg

Rešitev naloge:

  • Nalogo lahko rešujemo na več načinov
  • Mi jo bomo reševali s pomočjo nadrazreda Turtle.class, ki ga najdemo na predavanjih iz računalništva 2, Predavanja 11.11.2005 in pri domačih nalogah 4.Domača Naloga, ogrodje.
  • Nadrazred Turtle vsebuje metode, s katerimi bom risali naš trikotnik.
    • Metode in spremenljivke nadrazreda:
      • void barva (Color danaBarva): nastavi barvo za izris na danaBarva
      • void napisi(String sporocilo): na mestu želve izpiši sporočilo
      • void spi (int cakaj): spi za nekaj milisekund
      • void krog (double radij): nariše krog z radijem r s središčem v trenutnem položaju želve
      • Turtle premakniSe(double levo, double naprej): obrni se za double stopinj v levo in pojdi za naprej točk naprej
      • Turtle narisi (double levo, double naprej): isto kot zgornja funkcija, le da pri premikanju za seboj pušča sled (riše)
      • void polnKrog (double radij): nariše poln krog z radijem radij
      • void polnPravokotnik (double sirina, double visina): nariše poln pravokotnik, želva se nahaja v sredini pravokotnika
    • Statične spremenljivke:
      • final int sirina: širina risalne površine
      • final int visina: višina risalne površine
      • final Color RDECA, MODRA, CRNA, SIVA, RUMENA, ROZA, ORANZNA, ZELENA, VIJOLICNA, BELA
  • Predstavljati si moramo, da naš trikotnik rišemo na nekakem "platnu".
  • V ukazni vrstici zapišemo, katerega reda trikotnik želimo narisati
  • Postavimo se v levi spodnji del platna
  • Narišemo osnovni trikotnik oziroma trikotnik ničtega reda
  • Paziti moramo, da se vedno vrnemo v isto točko in da imamo vedno isto smer (ker drugače ne bomo dobili iskani trikotnik)
  • Nato z rekurzijo, rišemo trikotnik oziroma trikotnike reda, ki smo ga izbrali


Program s katerim narišemo trikotnik Sierpinskega poljubnega reda.

/* S pomocjo zelve grafike (osnova je Turtle.class s pomoznima razredoma in dokumentacijo (kar  
   vse dobite v orodjih)) napisite program, ki narise vsaj eno izmed spodaj nastetih rekurzivnih       
   krivulj ali likov:
   1.Peanova krivulja,
   2.Hilbertova krivulja,...
 
   Vse te krivulje in like risemo s pomocjo rekurzije, saj je vsaka izmed krivulj reda n  
   sestavljena iz nekaj krivulj reda ''n - 1''.
 
  **/
 
public class Sierpinski {
   public static void main(String[] args) {
 
      // red Serpinskega zapisemo iz ukazne vrstice
      int n = Integer.parseInt(args[0]);
 
      // naredimo zelvo in jo premaknemo v spodnji del platna, kjer risemo nas trikotnik
      Turtle zelva = new Turtle();
      zelva.premakniSe(-130, 300);
      zelva.premakniSe(130, 0);
      trikotnik(350, n, zelva);
   }
 
   // risemo trikotnik dolzine d, reda n
   public static void trikotnik(int d, int n, Turtle zelva) {
 
      // narisemo osnovni trikotnik oz trikotnik reda 0 in se vrnemo v zacetno pozicijo
      if (n == 0) {
         zelva.narisi(0, d);
	 zelva.narisi(120, d);
	 zelva.narisi(120, d);
	 zelva.premakniSe(120, 0);
      }
 
      // s pomocjo rekurzije narisemo trikotnik Sierpinski
      // vedno, ko narisemo trokotnik, se vrnemo v zacetno pozicijo (imeti moramo zacetno smer)
      else { 
         trikotnik(d / 2, n - 1, zelva);
	 zelva.premakniSe(0, d / 2);
         trikotnik(d / 2, n - 1, zelva);
         zelva.premakniSe(120, d / 2);
	 zelva.premakniSe(-120, 0);
	 trikotnik(d/2, n -1, zelva);
         zelva.premakniSe(-120, d / 2);
         zelva.premakniSe(120, 0);
      }
   }
}