7.3 Omat funktiot

Yhteenveto

Tehdään kaksi aliohjelmaa. Toinen piirtää ympyrän, kun annamme sille keskipisteen ja säteen. Toinen aliohjelma, piirtää neliön, kun annamme sille keskipisteen ja neliön sivun pituuden.




SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta ikkunan taustaväriksi valkea.
  3. Aseta täyttöväriksi punainen.
  4. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (100,100) ja säde 50.
  5. Kutsu aliohjelmaa: nelio. Välitä aliohjelmalle neliön keskipiste (250,250) ja neliön sivun pituus 200.
  6. Aloita aliohjelma ympyra (Määrittele kokonaislukumuuttujat x, y ja r).
    1. Piirrä ympyra komennolla: ellipse(x,y,2*r,2*r);, missä ympyrän keskipiste on (x,y) ja ympyrän leveys on 2*r ja ympyrän korkeus on 2*r.
  7. Aloita aliohjelma nelio (Määrittele kokonaislukumuuttujat x, y r)
    1. Piirrä neliö komennolla: rect(x-r/2,y-r/2, r, r). Koska aliohjelmalle välitettiin neliön keskipiste (x,y), niin neliön nurkkapiste (x-r/2,y-r/2) saadaan aikaiseksi vähentämällä neliön keskipisteestä puolet neliön sivun pituudesta. Neliön sivun pituus on muuttuja r.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,400); // Ikkunan koko
background(255); // Valkea taustaväri
fill(255,0,0); // Punainen täyttöväri
}

void draw() {
ympyra(100,100,50);
nelio(250,250,200);
}

void ympyra(int x, int y, int r) {
ellipse(x,y,2*r,2*r);
}

void nelio(int x, int y, int r) {
rect(x-r/2,y-r/2,r,r);
}

Aliohjelma eli funktio

Haluamme luoda oman komennon ympyra(x,y,r); missä (x,y) on ympyrän keskipiste, r on ympyrän säde. Kuinka se onnistuu? Tällöin sanotaan, että luodaan aliohjelma eli funktio, jota pääohjelmasta void draw () kutsutaan nimellä. Aliohjelma, joka piirtää ympyrän, on seuraavanlainen.

void ympyra(int x, int y, int r) {
ellipse(x,y,2*r,2*r);
}


Ympyrä piirretään ellipse(x,y,a,b); komennon avulla, missä (x,y) on ellipsin keskipiste ja a on ellipsin leveys ja b on ellipsin korkeus. Jos säde on r, niin ellipsin leveys ja korkeus ovat tällöin 2*r. Nyt voimme ellipse(x,y,a,b)-komennolla piirtää ympyrän.

Jos ajat ohjelman, niin mitään ei tapahdu. Miksi? Oma komento ympyra(x,y,r); suoritetaan vain pääohjelmasta kutsumalla eli funktiosta: void draw (); Sanotaan, että funktiota tällöin kutsutaan. Vuorovaikutus pääohjelman ja aliohjelman välillä on seuraava.



Kokonainen ohjelma on seuraavanlainen.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta ikkunan taustaväriksi valkea.
  3. Aseta täyttöväriksi vihreä.
  4. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (200,200) ja säde 50.
  5. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle neliön keskipiste (300,300) ja säde 20.
  6. Aloita aliohjelma ympyra (Määrittele kokonaislukumuuttujat x, y ja r).
    1. Piirrä ympyra komennolla: ellipse(x,y,2*r,2*r);, missä ympyrän keskipiste on (x,y) ja ympyrän leveys on 2*r ja ympyrän korkeus on 2*r.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,400); // ikkunan koko
background(255); // Valkea taustaväri
fill(0,255,0); // Vihreä täyttöväri
}

void draw() {
ympyra(200,200,50); // Aliohjelman kutsuminen
ympyra(300,100,20); // Kutsutaan aliohjelmaa toisen kerran.
}

void ympyra(int x, int y, int r) {
ellipse(x,y,2*r,2*r);
}


Kun ajat ohjelman, niin se näyttää tältä.




Kuten huomaat, aliohjelmaa voidaan kutsua pääohjelmasta niin monta kertaa kuin haluat. Aliohjelmat mahdollistavat jo käytössä olevien piirtokomentojen suomentamisen, mutta voit luoda mihin tarkoitukseen tahansa oman aliohjelman eli funktion. Omien funktioiden eli aliohjelmien käyttäminen lyhentää pääohjelmaa ja ongelma saadaan pilkottua osiin.

Yleisesti aliohjelma muodostetaan seuraavan rakenteen mukaisesti.

void aliohjelman_nimi (aliohjelman_muuttujat) {
Komennot;
}


Tässä sana void tarkoittaa sitä, että funktio ei palautua mitään arvoa, vaan funktio suoritetaan itsenäisenä. Seuraavassa kappaleessa tutkitaan funktioita, jotka palauttavat arvoja takaisin pääohjelmaan.

Kuten huomaat, myös lohkot void setup () ja void draw () ovat funktioita. Sekä kaikki aikaisemmin käydyt piirtokomennot. Nämä funktiot on piilotettu ohjelman mukana latautuviin kirjastoihin.

Aliohjelmien nimeämisessä on samat käytännöt kuin muuttujien nimeämisessä. Käytännössä tämä tarkoittaa sitä, että aliohjelmien nimessä et voi käyttää skandimerkkejä (ö,ä,å), erikoismerkkejä, etkä välilyöntejä.

Aliohjelmassa translate(x,y) ja scale(koko); -komennot

Katsotaan seuraavaa esimerkkiä.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta ikkunan taustaväriksi valkea.
  3. Aseta täyttöväriksi punainen.
  4. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (110,110) ja säde 20.
  5. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (180,110) ja neliön sivun pituus 50.
  6. Aloita aliohjelma ympyra (Määrittele kokonaislukumuuttujat x, y ja r).
    1. Ota nykyinen koordinaatisto muistiin.
    2. Siirrä origoa x:n verran oikealle ja y:n verran alas.
    3. Skaalaa kuviota isoamksi tai pienemmäksi kertoimella: 2*r/100.0, missä 2*r on ympyrän halkaisija.
    4. Piirrä ympyrä origoon eli pisteeseen (0,0). Ympyrän halkaisija on 100 eli leveys ja korkeus.
    5. Palauta muistissa oleva koordinaatisto takaisin.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup() {
size(400, 400); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(255,0,0); // Täyttöväri punainen
}

void draw() {
ympyra(110, 110,20); // Kutsutaan aliohjelmaa
ympyra(180, 110,50);
}

void ympyra(int x, int y, int r) {
pushMatrix(); // Otetaan nykyinen koordinaatisto muistiin
translate(x, y); // Siiretään origo pisteeseen (x,y)
scale(2*r/100.0); // Skaalataan kuviota isommaksi tai pienemmäksi.
ellipse(0,0,100,100); // Piirretään origoon ympyrä, jonka halkaisija on 100
popMatrix(); // Palautetaan koordinaatisto takaisin
}


Ohjelman tulostus on seuraavanlainen.




Piirretään origoon ympyrä, jonka halkaisija on 100 px. Tässä ympyrä siirretään eri paikkaan translate(x,y); komennolla ja kuvion koko saadaan isommaksi scale(2*r/100.0); komennolla. Huomaa, että laskukaava 2*r/100.0 on kerroin, kuinka moninkertaiseksi kuvio skaalataan. Jos kerroin on yli yksi, kuvio suurenee alkuperäisestä (100 px). Jos kerroin on alle ykkösen, niin kuvio pienenee alkuperäisestä (100 px).

Nyt emme tarvitse välittää koordinaattitietoja, sekä kokotietoja ellipse(x,y,a,b); funktioon. Tämä oivallus helpottaa monimutkaisten kuvioiden siirtämistä ja suurentamista eri paikkaan. Koska kuvion paikka voidaan määrätä translate(x,y)-komennolla ja kuvion koko voidaan määrätä scale(koko)-komennolla. Tärkeintä on lopuksi siirtää origo samassa muodossa takaisin alkuperäiseen paikkaan. Helpoiten tämä onnistuu pushMatrix(); ja popMatrix(); komennoilla. pushMatrix() ottaa koordinaatiston muistiin ja popMatrix() palauttaa muistissa olevan koordinaatiston.

Esimerkki: Ympyrä matematiikan xy-koordinaatistossa

Tehdään aliohjelma, joka piirtää ympyrän matematiikan xy-koordinaatistoon. Tehdään aliohjelma, siten, että voimme valita ympyrän keskipisteen (x,y), säteen r ja värin. Ohjelma on seuraava.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta ikkunan taustaväriksi valkea.
  3. Aseta täyttöväriksi musta.
  4. Siirrä origoa puolet ikkunan leveydestä oikealle ja puolet ikkunan korkeudesta alaspäin eli siirrä origo ikkunan keskelle.
  5. Peilaa y-akseli eli y:n arvot kasvaa nyt ylöspäin.
  6. Piirrä vaakaviiva pisteiden (-width/2,0) ja (width/2,0) välille, missä width on ikkunan leveys (x-akseli).
  7. Piirrä pystyviiva pisteiden (0,height/2) ja (0,-height/2) välille, missä height on ikkunan korkeus (y-akseli).
  8. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (100,100), säde 50 ja väriarvo: "vihreä".
  9. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (-50,150), säde 25 ja väriarvo: "punainen".
  10. Kutsu aliohjelmaa: ympyra. Välitä aliohjelmalle ympyrän keskipiste (-50,-110), säde 25 ja väriarvo: "keltainen".
  11. Aloita aliohjelma ympyra (Määrittele kokonaislukumuuttujat x, y, r ja merkkijonomuuttuja vari)
    1. Jos vari-muuttuja on "valkea", niin silloin aseta täyttöväriksi valkea.
    2. Jos vari-muuttuja on "musta", niin silloin aseta täyttöväriksi musta.
    3. Jos vari-muuttuja on "harmaa", niin silloin aseta täyttöväriksi harmaa.
    4. Jos vari-muuttuja on "punainen", niin silloin aseta täyttöväriksi punainen.
    5. Jos vari-muuttuja on "vihreä", niin silloin aseta täyttöväriksi vihreä.
    6. Jos vari-muuttuja on "sininen", niin silloin aseta täyttöväriksi sininen.
    7. Jos vari-muuttuja on "keltainen", niin silloin aseta täyttöväriksi keltainen.
    8. Jos vari-muuttuja on "magneta", niin silloin aseta täyttöväriksi magneta.
    9. Jos vari-muuttuja on "syaani", niin silloin aseta täyttöväriksi syaani.
    10. Piirrä ympyrä komennolla: ellipse(x,y,2*r,2*r), missä ympyrän keskipiste on (x,y) ja ympyrän halkaisja on 2*r.
    11. Nollaa täyttöväri eli asteta täyttöväriksi musta.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,400); // ikkunan koko
background(255); // taustan väri valkea
fill(0); // Musta täyttöväri
}

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // Peilaa y-koordinaatit
line(-width/2,0,width/2,0); // vaaka-akseli
line(0,height/2,0,-height/2); // pystyakseli
ympyra(100,100,50,"vihreä");
ympyra(-50,150,25,"punainen");
ympyra(-70,-110,80,"keltainen");
}

void ympyra(int x,int y,int r, String vari) {
if (vari == "valkea") {
fill(255,255,255);
} else if (vari == "musta") {
fill(0,0,0);
} else if (vari == "harmaa") {
fill(128,128,128);
} else if (vari == "punainen") {
fill(255,0,0);
} else if (vari == "vihreä") {
fill(0,255,0);
} else if (vari == "sininen") {
fill(0,0,255);
} else if (vari == "keltainen") {
fill(255,255,0);
} else if (vari == "syaani") {
fill(0,255,255);
} else if (vari == "magneta") {
fill(255,0,255);
}
ellipse(x,y,2*r,2*r);
fill(0); // Värin nollaus
}


Kuten huomasit, niin aliohjelmaan voidaan myös välittää merkkijono-tyyppistä tietoa. Kun välität merkkijono tyyppistä tietoa, niin laita välitettävä tieto lainausmerkkien (" ") väliin. Ohjelman tulostus on seuraava.




Matematiikan xy-koordinaatisto luodaan komennoilla translate(width/2,height/2) ja scale(1,-1); Komento: translate(width/2,height/2); siirtää origon ikkunan keskelle ja komento: scale(1,-1);peilaa y-koordinaatin arvot eli y kasvaa ylöspäin. x- ja y-akselit on hyvä myös tulostaa. Ne saat tulostettua line()-komennolla, jossa on käytetty komentoja width ja height funktion parametreina. Tämä on järkevää, koska silloin xy- koordinaatisto saadaan aina ikkunan keskelle riippumatta siitä mikä on ikkunan koko.

Esimerkki: Naama


Kuinka piirtäisit kuvan mukaisen naaman? Origo on ikkunan keskellä. Seuraavilla komennoilla saataisiin naama aikaiseksi.

 fill(200,100,50);  // Ruskea väri
ellipse(0,0,200,200); // Taakse tuleva ympyrä
fill(100,200,200); // Sininen väri
ellipse(-25,-25,40,80); // Vasen silmä
ellipse(25,-25,40,80); // Oikea Silmä
fill(0); // Musta väri
ellipse(-25,0,20,20); // Silmän mustuainen, vasen
ellipse(25,0,20,20); // Silmän mustuainen, oikea
fill(255,0,0); // Punainen väri
arc(0,50,100,50,radians(0),radians(180),PIE); // Suu

Mietitään seuraavaksi, kuinka tästä kannattaa tehdä aliohjelma. Kaikkein järkevin tapa on käyttää aliohjelmassa translate(x,y) ja scale(r); komentoja. Jolloin pääohjelma ja aliohjelma on seuraavanlaiset.

SANALLINEN ALGORITMI
  1. Aseta ikkunan kooksi 400 px vaakaan ja 400 px pystyyn.
  2. Aseta ikkunan taustaväriksi valkea.
  3. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja a, joka saa alkuarvon 50. Toista niin kauan kun a on pienempi tai yhtä suuri kuin 350. Kasvata muuttujaa a 50:llä).
    1. Kutsu aliohjelmaa naama. Välitä aliohjelmalle naaman keskipiste (a,50) ja naaman koko 50.
    2. Kutsu aliohjelmaa naama. Välitä aliohjelmalle naaman keskipiste (a,150) ja naaman koko 100.
    3. Kutsu aliohjelmaa naama. Välitä aliohjelmalle naaman keskipiste (a,300) ja naama koko 150.
  4. Aloita aliohjelma naama (Määrittele kokonaislukumuuttujat x, y, w)
    1. Ota nykyinen koordinaatisto muistiin.
    2. Siirrä origo x:n verran oikealle ja y:n verran alaspäin. Naama siirtyy origon mukana.
    3. Skaalaa kuvio isommaksi tai pienemmäksi suhteella w/200.0.
    4. Aseta ruskea väri, jonka väriarvo on (R=200,G=100,B=50).
    5. Piirrä hahmon pää eli ympyrä, jonka keskipiste on (0,0) ja halkaisija 200.
    6. Aseta sininen väri, jonka väriarvo on (R=100,G=200,B=200).
    7. Piirrä vasen silmä eli ellipsi, jonka keskipiste on (-25,-25), leveys 40 ja korkeus 80.
    8. Piirrä oikea silmä eli ellipsi, jonka keskipiste on (25,25), leveys 40 ja korkeus 80.
    9. Aseta musta väri.
    10. Piirrä silmän vasen mustuainen eli ympyrä, jonka keskipiste on (-25,0) ja halkaisija 20.
    11. Piirrä silmän oikea mustuainen eli ympyrä, jonka keskipiste on (25,0) ja halkaisija 20.
    12. Aseta punainen väri.
    13. Piirrä suu eli sektori, jonka keskipiste on (0,50), leveys 100 ja korkeus 50, kulman aloituskulma on 0° (idässä) ja lopetuskulma on 180° (lännessä).
    14. Palauta muistissa oleva koordinaatisto takaisin.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup() {
size(400, 400); // Ikkunan koko
background(255); // Taustaväri valkoinen
}
void draw() {
for (int a=50; a <= 350; a=a+50) {
// a saa arvoja 50,100,150,200,250,300,350
naama(a,50,50); // Ylärivi, Huomaa x-koordinaatissa muuttuja a
naama(a,150,100); // Keskellä
naama(a,300,150); // Alarivi
}
}
void naama(int x, int y, int w) {
pushMatrix(); // Koordinaatisto muistiin
translate(x, y); // Siirrä hahmoa x:n verran oikealla ja y:n verran alas
scale(w/200.0); // Skaalaa kuvio isommaksi tai pienemmäksi
fill(200,100,50); // Ruskea väri
ellipse(0,0,200,200); // Taakse tuleva ympyrä
fill(100,200,200); // Sininen väri
ellipse(-25,-25,40,80); // Vasen silmä
ellipse(25,-25,40,80); // Oikea Silmä
fill(0); // Musta väri
ellipse(-25,0,20,20); // Silmän mustuainen, vasen
ellipse(25,0,20,20); // Silmän mustuainen, oikea
fill(255,0,0); // Punainen väri
arc(0,50,100,50,radians(0),radians(180),PIE); // Suu
popMatrix(); // Palauta muistissa oleva koordinaatisto
}


Kun ohjelma ajetaan, se tulostaa seuraavaa.




Kuten huomasit, lisäämällä pääohjelmaan for-silmukka, aliohjelmaa voidaan kutsua useasti.

Muutetaan pääohjelmassa koodi seuraavasti.

SANALLINEN ALGORITMI
  1. Siirrä origoa 200 oikealle ja 200 alas eli siirrä origo ikkunan keskelle.
  2. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja a, joka saa alkuarvon 0. Toista niin kauan kun a on pienempi tai yhtä suuri kuin 12. Kasvata muuttujaa a yhdellä).
    1. Pyöritä koordinaatistoa 30° myötäpäivään aina kun muuttuja a kasvaa for-silmukassa.
    2. Kutsu aliohjelmaa naama. Välitä aliohjelmalle naaman keskipiste (100,0) ja naaman koko 50.

void draw() {
translate(200,200);
for (int a=0; a <= 12; a++) { // a = 0,1,2,3,4,5,6,7,8,9,10,11,12
rotate(radians(30)); // Pyöritä 30° myötäpäivään
naama(100,0,50); // Aliohjelman kutsu
}
}

Tulostuu 12 kappaletta naamoja ympyrän kehälle.




Kuinka naamat saataisiin spiraalille? Muutetaan pääohjelma seuraavanlaiseksi.

SANALLINEN ALGORITMI
  1. siirrä origoa 200 oikealle ja 200 alas eli siirrä origo ikkunan keskelle.
  2. Määrittele for-silmukka (Määrittele kokonaislukumuuttuja a, joka saa alkuarvon 0. Toista niin kauan kun a on pienempi tai yhtä suuri kuin 230. Kasvata muuttujaa a 10:llä).
    1. Pyöritä koordinaatistoa 30° myötäpäivään aina kun muuttuja a kasvaa for-silmukassa.
    2. Kutsu aliohjelmaa naama. Välitä aliohjelmalle naaman keskipiste (a,0) ja naaman koko a. Koska muuttuja on mukana keskipisteessä, niin naama siirtyy kohti ulkoreunaa, kun a kasvaa for-silmukassa. Koska muuttuja on mukana naaman koossa, niin naaman koko kasvaa samaan tahtiin kuin muuttuja a kasvaa for-silmukassa.

void draw() {
translate(200,200); // Origo ikkunan keskelle
for (int a=0; a <= 360; a=a+10) { // a = 0,10,20,30,...360
rotate(radians(30)); // Pyöritä 30 myötäpäivään
naama(a,0,a); // Aliohjelma kutsu
}
}


Naama menee kohti ulkoreunaa ja samalla koko kasvaa.



Aliohjelmaa voidaan myös ohjata hiirellä. Tehdään seuraava muutos pääohjelmassa olevaan koodiin.

void draw() {
naama(mouseX,mouseY,100);
}


Tällöin ohjelma tulostaa seuraavaa, kun liikutat hiirtä ikkunassa:




Voit kokeilla vielä liikutella hahmoa laskurilla.