7.1 Konnagrafiikkaa

Yhteenveto

  • Määritellään neljä funktiota eli aliohjelmaa nimeltään eteen(); taakse(); oikealle(); ja vasemmalle(); Näiden avulla voimme liikkua matematiikan xy-koordinaatistossa.
  • Jotta matematiikan xy-koordinaatisto olisi käytössä, niin alkuun on laitettava translate(width/2,height/2); komento, joka laittaa origon ikkunan keskelle ja scale(1,-1); komento, joka peilaa y-koordinaatin arvot.
  • Funktiota void draw () voimme kutsua pääohjelmaksi.
  • Aliohjelmia voidaan kutsua pääohjelmasta. Aliohjelma suoritetaan vain, jos sitä kutsutaan.
  • Kutsun yhteydessä pääohjelmasta välitetään aliohjelmaan kokonaislukutietoa, joiden avulla aliohjelma osaa liikuttaa punaista kynää tai kääntyä halutun asteen verran.
  • Tällä tunnilla tehdään erilaisia kuvioita käyttäen valmiiksi määriteltyjä aliohjelmia.

Konnagrafiikkaa

Tässä kappaleessa tutustutaan funktioihin, mutta mitä ovat funktiot? Funktiot ovat aliohjelmia, joita kutsutaan pääohjelmasta. Tutkitaan aluksi valmista esimerkkiä funktioiden käytöstä. Luodaan neljä funktiota: eteen(); taakse(); vasemmalle; ja oikealle();.
Funktioiden merkitys
FunktioMerkitys

eteen(askel);

Aliohjelman avulla siirrytään askeleen osoittama määrä eteenpäin. Kun liikutaan eteenpäin, niin samalla piirretään punaista viivaa. Liikkuminen tapahtuu for-silmukan avulla. Lopuksi myös koordinaatiston origo siirretään tähän loppupisteeseen.

taakse(askel);

Aliohjelman avulla siirrytään askeleen osoittama määrä taaksepäin. Kun liikutaan taaksepäin, niin samalla piirretään punaista viivaa. Liikkuminen tapahtuu for-silmukan avulla. Lopuksi myös koordinaatiston origo siirretään tähän loppupisteeseen.

vasemmalle(kulma);

Aliohjelma, jonka avulla etenemissuunta käännetään kulman osoittama määrä vasemmalle eli vastapäivään.

oikealle(kulma);

Aliohjelma, jonka avulla etenemissuunta käännetään kulman osoittama määrä oikealle eli myötäpäivään.


Koska komennoilla: eteen(), taakse(), vasemmalle() ja oikealle() ohjataan ikään kuin kilpikonnaa ruudulla, niin näiden funktioiden avulla luotua grafiikkaa nimitetään usein konnagrafiikaksi.

Tutkitaan tarkemmin funktioita void draw () ja void eteen (). Funktiota void draw () voidaan myös kutsua nimellä pääohjelma, koska se suoritetaan aina automaattisesti. Sitä vastoin kirjoittamamme funktio void eteen () suoritetaan ainoastaan siinä tapauksessa, että sitä kutsutaan. Kutsuminen tapahtuu pääohjelmassa kirjoittamalla aliohjelman eli funktion nimi: eteen(100); Samalla aliohjelmalle voidaan välittää tietoa (kokonaisluku, desimaaliluku, merkki, merkkijono, totuusarvo). Välitettävä tieto kirjoitetaan sulkujen sisälle. Jotta aliohjelma ymmärtää välitettävän tiedon eli esimerkiksi 100, aliohjelmaan on määriteltävä muuttuja sulkujen sisälle. Nyt muuttuja on kokonaislukumuuttuja nimeltään askel ja se saa kutsumisen yhteydessä arvon 100. Oheinen kuva havainnollistaa asiaa.



Kokonainen ohjelma, jossa on pääohjelma ja harjoituksissa tarvittavat aliohjelmat, on seuraava.

// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
int x = 0;
int y = 0;
int w = 10; // Kynän paksuus (voit muuttaa)
void setup () {
size(800,800); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(255,0,0); // Kynän väri punainen (voit muuttaa)
noStroke(); // Ei reunaviivaa
noLoop(); // Suoritetaan void draw () lohko kerran
}
void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
eteen(100);
vasemmalle(45);
eteen(200);
oikealle(120);
eteen(300);
}
void eteen(int askel) {
for (int a = 0; a < askel; a++) {
x = x + 1;
ellipse(x,y,w,w);
}
translate(askel,0);
x = 0;
}
void taakse(int askel) {
for (int a = 0; a < askel; a++) {
x = x - 1;
ellipse(x,y,w,w);
}
translate(-askel,0);
x = 0;
}
void vasemmalle(int kulma) {
rotate(radians(kulma));
}
void oikealle(int kulma) {
rotate(radians(-kulma)); }

Ohjelman suoritus näyttää tältä.


Kun pääohjelmassa eli void draw () lohkossa tehdään seuraavat komennot:

eteen(100);
vasemmalle(45);
eteen(200);
oikealle(120);
eteen(300);

niin saadaan aikaiseksi yllä olevan kuvan mukainen reitti. Tärkeintä on huomata, että funktiot eteen(), taakse (), vasemmalle() ja oikealle() suoritetaan vain ja ainoastaan silloin kun sitä kutsutaan void draw ()-lohkossa. Katsotaan tarkemmin luomaamme eteen()- funktiota.

void eteen(int askel) {
     for (int a = 0; a < askel; a++) {
x = x + 1;
ellipse(x,y,w,w);
}
translate(askel,0);
x = 0;
}

Funktio alkaa sanalla: void. Tämä tarkoittaa, että funktio ei palauta mitään arvoa takaisin. Tämän jälkeen tulee funktion nimi eli eteen. Suluissa on määritelty askel-niminen kokonaislukumuuttuja. Kun kirjoitamme komennon: eteen(100);, niin askel-muuttuja saa arvon 100. Vastaavasti kun kirjoitamme komennon: eteen(200);, niin askel-muuttuja saa arvon 200. Askel-muuttujalla määräämme matkan, jonka etenemme eteenpäin. Itse liikkuminen tapahtuu for-silmukan avulla, jossa x-koordinaatin arvoa kasvatamme laskurin x = x + 1 avulla annetun askeleen verran. For-silmukka käy arvot 1, 2, 3,..., askel läpi, niin samalla x kasvaa yhteensä askel-muuttujan verran. Kun liikkuminen tapahtuu järjestyksessä: 1, 2, 3, ..., askel, niin saamme samalla piirrettyä reitin ellipse()- komennolla. Liikkuminen tapahtuu aina eteenpäin oikealle. Lopuksi siirrämme origon kulkemaamme loppupisteeseen. Koska origo on loppupisteessä, niin laitamme x:lle takaisin alkuarvon nolla. Aliohjelman avulla liikumme aina eteenpäin ja samalla kuljetamme origoa mukana. Tässä kynän paksuus on kuvattu muuttujalla w.

Funktiot oikealle() ja vasemmalle() ainoastaan pyörittävät koordinaatistoa antamamme kulman verran.

Esimerkki: Tiimalasi

Haluaisimme piirtää tiimalasin eteen(), taakse(), oikealle() ja vasemmalle() funktioilla. Kuinka se onnistuisi? Piirrämme sitä varten apukuvion, joka havainnollistaa kulkemaamme reittiä.



Lähdetään liikkeelle mustasta pisteestä. Mennään aluksi 100 askelta eteenpäin, käännytään 120° vasemmalle, mennään 200 askelta eteenpäin, käännytään 120° oikealle, mennään 100 askelta eteenpäin, käännytään 120° oikealle ja lopuksi mennään 200 askelta eteenpäin. Olemme nyt tulleet takaisin lähtöpisteeseen. Kirjoitamme void draw ()-lohkoon seuraavat komennot.

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
eteen(100);
vasemmalle(120);
eteen(200);
oikealle(120);
eteen(100);
oikealle(120);
eteen(200);
}

Nyt ohjelma piirtää tiimalasin.

Esimerkki: Neliö

Kuinka funktioilla: eteen(), vasemmalle() ja oikealle() voitaisiin piirtää neliö, jonka sivun pituus on 200?



Neliö saadaan aikaiseksi liikkumalla aina eteenpäin 200 askelta ja sen jälkeen kääntymällä aina samaan suuntaan 90 astetta. Kun teet nämä komennot neljä kertaa, niin saat aikaiseksi neliön eli kirjoita void draw ()-lohkoon seuraavat komennot.

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
eteen(200);
vasemmalle(90);
eteen(200);
vasemmalle(90);
eteen(200);
vasemmalle(90);
eteen(200);
vasemmalle(90);
}

Huomaa, että alussa suunta on oikealle. Myös lopussa suunnan pitäisi olla oikealle. Voit kätevästi tarkistaa tämän summaamalla kulmat yhteen. Jos summaksi tulee 360 astetta, niin suunta lopussa on sama kuin alussa. Kuten huomaat, käytämme tässä matematiikan xy-koordinaatistoa, joten älä poista translate(400,400); ja scale(1,-1); komentoja.

Entä jos haluaisimme luoda funktion, joka piirtäisi neliön? Myös funktio voi kutsua toista funktiota. Yksikertaisesti kirjoitamme yllä olevista komennoista uuden funktion, joka on muotoa.

void nelio(int sivu) {
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
}

Myös nelio-funktioon kannattaa laittaa oma kokonaislukumuuttuja sivu, niin voimme halutessamme muuttaa neliön kokoa. Nyt riittää, kun kutsumme kerran nelio()-funktiota void draw ()-lohkossa. Kokonainen ohjelma näyttää nyt tältä.

int x = 0; 
int y = 0;
int w = 10; // Kynän paksuus
void setup () {
size(800,800); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(255,0,0); // Täyttöväri punainen
noStroke(); // Ei reunaviivaa
noLoop(); // Suoritetaan void draw () lohko kerran
}

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaatisto peilaamalla y-koordinaatit
nelio(200);
}

void nelio(int sivu) {
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
eteen(sivu);
vasemmalle(90);
}

void eteen(int askel) {
for (int a = 0; a < askel; a++) {
x = x + 1;
ellipse(x,y,w,w);
}
translate(askel,0);
x = 0;
}
void taakse(int askel) {
for (int a = 0; a < askel; a++) {
x = x - 1;
ellipse(x,y,w,w);
}
translate(-askel,0);
x = 0;
}
void vasemmalle(int kulma) {
rotate(radians(kulma));
}

void oikealle(int kulma) {
rotate(radians(-kulma));
}

Esimerkkejä neliö-funktion käytöstä



Kuvan mukainen kuvio saadaan aikaiseksi kutsumalla nelio()-funktiota seuraavasti void draw ()-lohkossa.

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
nelio(100);
nelio(200);
nelio(300);
}

Entä jos haluaisimme piirtää sisäkkäiset neliöt?



Kuvan mukainen kuvio saadaan aikaiseksi kutsumalla nelio()-funktiota seuraavasti void draw ()-lohkossa.

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
nelio(100);
translate(-50,-50);
nelio(200);
translate(-50,-50);
nelio(300);
}

Eli siirrämme origoa 50 px vasemmalle ja 50 px alaspäin komennolla translate(-50,-50). Translate()-komennolla voimme hypätä uuteen paikkaan, joka on uuden kuvion aloituspiste. Jos haluat siirtyä uuteen paikkaan eteen(); tai taakse(); komennoilla ilman, että piirretään punaista väriä, niin voit muuttaa tarvittaessa piirtoväriä. Laita piirtoväriksi tällöin sama väri kuin on taustassa, niin viiva ei näy.

Haluatko pyörittää neliötä?



Kuvan mukainen kuvio saadaan aikaiseksi kutsumalla nelio()-funktiota seuraavasti void draw ()-lohkossa.

void draw () {
translate(width/2,height/2); // Origo ikkunan keskelle
scale(1,-1); // xy-koordinaastio peilaamalla y-koordinaatit
nelio(100);
vasemmalle(120);
nelio(100);
vasemmalle(120);
nelio(100);
vasemmalle(120); // Palautetaan suunta oikealle
}

Eli aina ennen uuden neliön piirtämistä pyöritämme vaaka-akselia 120 astetta vasemmalle.