Ohjelmointi ja taide, osa 1: Geometriset kuviot

Ohjelmoinnin, matematiikan ja taiteen yhdistäminen mahdollistaa projektit, joissa hyödynnetään tekniikkaa luovalla tavalla. Julkaisemme aiheesta kolmiosaisen juttusarjan. Tässä ensimmäisessä artikkelissa tutustumme JavaScript-pohjaiseen ohjelmointikieleen P5js ja sen perusgrafiikkakomentoihin. Lähdemme liikkeelle geometrisistä kuvioista, jotka on sidottu xy-koordinaatistoon. Kun mukaan lisäämme ohjelmoinnin toisto- ja ehtolauseita, saamme helposti kuvioista monimutkaisempia ja saamme mukaan vuorovaikutusta.

Toinen osa Rekursio (Dimensio 21.7.2022)

Kolmas osa Taidetta laskukaavoilla (Dimensio 4.8.2022)

Perusgrafiikkakomennot

Aluksi katsomme, kuinka geometriset kuviot, kuten esimerkiksi piste, jana, kolmio, nelikulmio, suorakulmio ja ellipsi saadaan aikaiseksi. 

Ohjeet eri geometriakomennoista. Ohjelmoinnin matematiikan ja taiteen yhdistäminen.
Kuva 1: Kuvassa on esitetty komennot pisteen, janan, kolmion, nelikulmion, suorakulmion ja ellipsin piirtämiseksi yleisessä muodossa. Käytännössä komennon parametrien paikalle on sijoitettava jokin lukuarvo.

P5js-ohjelmointikielessä kaikki grafiikkakomennot on sidottu xy-koordinaatistoon. Origo on ikkunan vasemmassa yläreunassa, josta x:n arvot kasvavat oikealle ja y:n arvot kasvavat alaspäin. Jokaiselle kuviolle on oma grafiikkakomento eli funktio, joka koostuu komennon nimestä ja komentoon välitettävistä lukuarvoista eli parametrista. Esimerkiksi jos haluamme piirtää pisteen xy-koordinaatiston paikkaan (100,200), kirjoitamme komennon point(100,200);

Tehdään kokonainen ohjelma, joka piirtää nämä kuusi peruskuviota. Lisäämme koodin mukaan kommentteja, jotta koodia on helpompi ymmärtää. Kaikki kommentit alkavat kahdella kauttaviivalla eli //.

Esimerkki 1: Ohjelma, joka piirtää suorakulmion, kolmion, puolisuunnikkaan, janan, ympyrän ja pisteen xy -koordinaatistoon, jonka leveys on 600 ja korkeus 400. Lähde: https://editor.p5js.org/riekkinen/sketches/M5IzS1xu2

function setup() {
  createCanvas(600, 400); // Ikkunan eli koordinaatiston koko 
}

function draw() {
  background(128);      // Tyhjennä tausta ja väritä se harmaaksi
  strokeWeight(3);      // Aseta viivan paksuudeksi 3 px
  fill(255,0,0);        // Aseta täyttöväriksi punainen
  rect(20,50,100,200);  // Piirrä suorakulmio
  fill(0,255,0);        // Aseta täyttöväriksi vihreä
  triangle(200,50,300,50,300,200); // Piirrä kolmio
  fill(0,0,255);        // Aseta täyttöväriksi sininen
  quad(400,50,500,50,550,200,350,200); // Piirrä puolisuunnikas
  line(50,300,150,350); // Piirrä jana 
  fill(255,255,0);      // Aseta täyttöväriksi keltainen
  ellipse(300,300,100,100); // Piirrä ympyrä
  strokeWeight(10);     // Aseta viivan paksuudeksi 10
  point(450,300);       // Piirrä piste 
}

Kuten esimerkistä huomasimme, ohjelma koostuu kahdesta lohkosta eli setup- ja draw-lohkoista. Setup-lohko suoritetaan kerran ja siksi setup-lohkossa ovat ne komennot, jotka pysyvät muuttumattomana koko ohjelman suorituksen ajan. Yksi tällainen komento on createCanvas(x,y), jonka avulla määritellään ikkunan eli xy-koordinaatiston koko. Kaikki lohkon sisällä oleva komennot tulevat kaarisulkujen { ja } väliin, joiden merkitys on sama kuin aloita ja lopeta.

Draw-lohkoa voisi kutsua pääohjelmaksi, jonne komennot eli funktiot pitää kirjoittaa suoritusjärjestyksessä.  Draw-lohko on ikuisessa silmukassa eli tällä mahdollistuu vuorovaikutus. Palaamme tähän vuorovaikutukseen toisessa esimerkissä. Kun katsot koodia hieman tarkemmin, huomaat että jokainen kuvio on piirretty eri värillä. Koska komennot suoritetaan järjestyksessä yksi kerrallaan, niin ennen piirtokomentoa on annettava komento, joka muuttaa kuvion väriä. Kuvion täyttöväri voidaan asettaa komennolla fill(R, G, B), missä R tarkoittaa punaista, G tarkoittaa vihreää ja B tarkoittaa sinistä väriarvoa. Kukin parametri voi saada arvoja 0:sta 255:een ja näitä kolmea arvoa muuttelemalla voimme saada aikaiseksi 2563 = 16 777 216 erilaista värisävyä. 

Taulukko 1: Esimerkin 1 komennot selitettynä

KomentoMerkitys
createCanvas(600, 400);    Luo xy-koordinaatiston, joka koko on 600 px oikealle ja 400 px alaspäin laskettuna ikkunan vasemmasta yläkulmasta.
background(128);     Tyhjentää taustan ja asettaa harmaan taustavärin. 0 = musta, 128 = harmaa, 255 = valkea.
strokeWeight(3);     Asettaa viivan paksuudeksi 3 px
fill(255,0,0);       Asettaa punaisen täyttövärin. Värit määräytyvät luvuista R = 255, G = 0, B = 0.
rect(20,50,100,200);  Piirtää suorakulmion, jonka vasemman yläkulman koordinaatti on (20,50) ja leveys on 100 px ja korkeus 200 px.
triangle(200,50,300,50,300,200);Piirtää kolmion, jonka nurkkapisteet ovat (200,50), (300,50) ja (300,200).
quad(400,50,500,50,550,200,350,200);Piirtää nelikulmion, jonka nurkkapisteet ovat (400,50), (500,50), (550,200) ja (350,200).
line(50,300,150,350);Piirtää janan, jonka alkupiste on (50,300) ja loppupiste on (150,350).
ellipse(300,300,100,100);Piirtää ympyrän, jonka keskipiste on paikassa (300,300) ja halkaisija on 100.
point(450,300);       Piirtää pisteen, joka on paikassa (450,300).

Taulukko 2: RGB-värien muodostaminen komennolla fill(R,G,B)

Taulukko, josta näkee miten eri perusvärit luodaan RGB-arvoja yhdistämällä.

Kun ajat ohjelman, tulos näyttää tältä:

Perusmuodot piirrettynä harmaalle taustalle.
Kuva 2: Kuva havainnollistaa esimerkki 1 mukaisen ohjelman suorittamista. 

Vuorovaikutus

Ehtolause eli if-lause on muotoa

if (ehto) { komennot 1; } else { komennot 2; }

Jos ehto on voimassa, niin silloin suoritetaan komennot 1, muutoin suoritetaan komennot 2. Esimerkiksi ehtolause voisi olla muotoa:

if (mouseX < 200) { komennot 1; } else { komennot 2; }

Tämä tarkoittaa, että jos hiiren vaakasuuntainen paikka on pienempi kuin 200, niin silloin suoritetaan komennot 1. Vastaavasti jos ehto ei ole voimassa, niin silloin suoritetaan komennot 2. Tutkitaan tätä ehtoa esimerkin avulla.

Esimerkki 2: Vuorovaikutus

Tehdään seuraavaksi ohjelma, jossa kuvio ja kuvion väri muuttuvat toiseksi hiiren liikkeiden mukaan. Vuorovaikutus saadaan aikaiseksi if-lauseen avulla. Ensimmäisen if-lauseen avulla muutamme taustan ja kuvion väriä, eli kun hiiren vaakasuuntainen paikka on ikkunan puolesta välistä vasemmalle, asetamme punaisen täyttövärin ja sinisen taustavärin. Jos ehto ei pidä paikkaansa, niin asetamme sinisen täyttövärin ja punaisen taustavärin. Toisen if-lauseen avulla muutamme kuvion muotoa eli kun hiiren pystysuuntainen paikka on ikkunan puolesta välistä ylöspäin, niin piirrämme ympyrän, muutoin piirrämme neliön. Lähde: https://editor.p5js.org/riekkinen/sketches/-P8qSho1x

function setup() {
  createCanvas(400, 400);    // Ikkunan eli koordinaatiston koko 
  noStroke();                // Ei reunaviivaa
}                            // Lopeta setup-lohko

function draw () {
  if (mouseX < 200) {        // Jos hiiren vaakasuuntainen paikka
                             // on pienempi kuin 200, niin silloin
      fill(255,0,0);         // aseta täyttöväriksi punainen
      background(0,0,255);   // aseta taustaväriksi sininen
  } else {                   // muutoin (jos ehto ei ole voimassa)
      fill(0,0,255);         // aseta täyttöväriksi sininen
      background(255,0,0);   // aseta taustaväriksi punainen
  }                          // Lopeta if-lause
  if (mouseY < 200) {        // Jos hiiren pystysuuntainen paikka
                             // on pienempi kuin 200, niin silloin
    ellipse(200,200,200,200);// piirrä ympyrä
  } else {                   // muutoin (jos ehto ei ole voimassa)
    rect(100,100,200,200);   // piirrä suorakulmio
  }                          // Lopeta if-lause
}                            // Lopeta draw-lohko

Taulukko 3: Esimerkin 2 komennot selitettynä

KomentoMerkitys
noStroke();Asetus, joka poistaa kuvioista reunaviivan eli kuviot piirretään ilman reunaviivaa.
if (mouseX < 200) { } else { }Jos hiiren vaakasuuntainen paikka on pienempi kuin 200, suorita ensimmäisen kaarisulun sisällä olevat komennot. Mikäli ehto ei pidä paikkaansa, suorita silloin toisen kaarisulun sisällä olevat komennot.
if (mouseY < 200) { } else { }Jos hiiren pystysuuntainen paikka on pienempi kuin 200, suorita ensimmäisen kaarisulun sisällä olevat komennot. Mikäli ehto ei pidä paikkaansa, suorita silloin toisen kaarisulun sisällä olevat komennot.

Muut komennot on selitetty jo esimerkissä 1. Kun ajat ohjelman, niin se toimii seuraavalla tavalla:

Neljä mallikuviota, joista ilmenevät ohjelman eri mahdolliset tulosteet.
Kuva 3: Kuvassa on havainnollistettu kuvion värin ja muodon muuttumista hiiren liikkeiden mukaan. Kuvion väri muuttuu hiiren vaakasuuntaisen liikkeen mukaan ja kuvion muoto muuttuu hiiren pystysuuntaisen liikkeen mukaan. Koska draw-lohko on ikuisessa silmukassa, niin kuvion väri ja muoto tarkistetaan koko ajan if-lauseiden avulla. 

Toistolause eli for-silmukka

Lisätään vielä mukaan toistolause eli for-silmukka. For-silmukka on muotoa:

for (var muuttuja = alkuarvo; ehto; laskuri); 

Lyhenne var tulee sanasta variable, joka tarkoittaa muuttujaa. Esimerkiksi muuttujan a avulla for-silmukka voidaan kirjoittaa muodossa:

for (var a = 0; a < 36; a++);

Lause var a = 0 määrittelee muuttujan a, jolle annamme alkuarvon nolla. Ehto a < 36 kertoo, kuinka kauan silmukkaa toistetaan eli silmukkaa toistetaan, niin kauan kun a on pienempi kuin 36.  Laskuri a++ tarkoittaa samaa kuin laskutoimitus a = a + 1 eli a:n arvo kasvaa joka kierroksella yhdellä. Käytännössä a voi saada arvoja: 0, 1, 2, 3, …, 35 eli toistoja silmukassa on tällöin 36 kappaletta. Tehdään seuraavaksi ohjelma, joka piirtää 36 kappaletta janoja ympyrän kehälle.

Esimerkki 3: Pyörähdyskuviot. Lähde: https://editor.p5js.org/riekkinen/sketches/prXfySaiS

function setup() {
  createCanvas(400, 400);    // Aseta ikkunan koko 400 x 400
  angleMode(DEGREES);        // Aseta kulma-asteikko, jossa on 360°
}                            // Lopeta setup-lohko

function draw() {
  background(255,255,0);       // Aseta keltainen taustaväri
  translate(width/2,height/2); // Aseta origo ikkunan keskelle
  stroke(255,0,0);             // Aseta viivan väriksi punainen
  strokeWeight(3);             // Aseta viivan paksuudeksi 3
  for (var a = 0; a < 36; a++) {  // Toista silmukkaa 36 kertaa 
    line(0,0,200,0);           // Piirrä jana 
    rotate(10);                // Pyöräytä koordinaatistoa 10°
  }                            // Lopeta for-silmukka
}                              // Lopeta draw-lohko

Taulukko 3: Esimerkin 2 komennot selitettynä

KomentoMerkitys
angleMode(DEGREES);Ohjelmassa on oletuksena käytössä radiaanit. Tällä komennolla voidaan ottaa käyttöön kulman suuruuden ilmaisemiseen asteet.
translate(width/2, height/2);Komento siirtää origon ikkunan keskelle.
stroke(255,0,0);Komennolla voidaan asettaa reunaviivan väri. Tässä reunaviivan väri on punainen.
for (var a = 0; a < 36; a++) {}Silmukka, jossa a saa arvoja 0, 1, 2, 3, …, 35 eli silmukkaa toistetaan 36 kertaa.
rotate(10);Koko koordinaatistoa pyöritetään 10 astetta myötäpäivään.

Kun ajat ohjelman, niin lopputulos näyttää tältä:

36 viivasta koostuva tähti keltaisella pohjalla. Ohjelmoinnin matematiikan ja taiteen yhdistäminen.
Kuva 4: Kuvassa on havainnollistettu ohjelman suoritus: ensin siirretään origo ikkunan keskelle, sitten piirretään punainen vaakasuora viiva ja pyöräytetään koordinaatistoa 10° myötäpäivään origon suhteen. Kun viivan piirtämistä ja pyöräytystä toistetaan 36 kertaa, niin saamme aikaiseksi kuvan mukaisen kuvion. 

Taidetta geometrisillä kuvioilla

Otetaan lopuksi esimerkki, jonka voisi toteuttaa sekä askartelemalla paperille että ohjelmoimalla. Tehdään aluksi ohjelma, joka piirtää kaksi kolmiota, neliön ja neljäkkään kuten kuvassa.

Neljä eriväristä perusmuotoa vierekkäin.
Kuva 5: Ohjelmassa piirrettävät geometriset kuviot.

Tärkeintä on oivaltaa, että kolmio on tasasivuinen kolmio ja että neljäkäs on myös piirretty 60° kulmaan eli koostuu kahdesta tasasivuisesta kolmiosta. Kun nyt origo pidetään punaisen kolmion kärjessä ja kuviota pyöritetään 60 astetta kuusi kertaa, saadaan alla olevan kuvan mukainen geometrinen kuvio. Tässä kuvioista on poistettu reunaviiva, jolloin kuudesta tasasivuisesta kolmiosta muodostuu säännöllinen kuusikulmio.  

Perusmuodoista koostuva säteittäisymmetrinen kuvio. Ohjelmoinnin matematiikan ja taiteen yhdistäminen
Kuva 6: Kun peruskuvioita piirretään kuusi kertaa ja välissä pyöräytetään koordinaatistoa aina 60 astetta, saamme kuvan mukaisen kuvion. Tässä peruskuviot on piirretty ilman reunaviivaa.

Ohjelma, joka piirtää yllä olevan kuvion, on seuraavanlainen:

Esimerkki 4: Kuvioita pyörittämällä. Lähde: https://editor.p5js.org/riekkinen/sketches/5yWC84gRO

function setup() {
  createCanvas(800, 800);          // Ikkunan koko 800 x 800
  noStroke();                      // Poistetaan reunaviiva käytöstä
  angleMode(DEGREES);              // Aseta kulma-asteet
}                                  // Lopeta setup-lohko

function draw() {
  background(0);                   // Taustan väri mustaksi
  translate(width/2,height/2);     // Origo ikkunan keskelle
  for (var a = 0; a < 6; a++) {    // for-silmukka, jossa 6 toistoa
     fill(255,0,0);                // Punainen täyttöväri
     triangle(0,0,100,58,100,-58); // Piirrä kolmio
     fill(0,0,255);                // Sininen täyttöväri
     rect(100,-58,116,116);        // Piirrä neliö
     fill(0,255,0);                // Vihreä täyttöväri
     triangle(216,-58,316,0,216,58);// Piirrä kolmio
     fill(255,255,0);               // Keltainen täyttöväri
     quad(100,58,216,58,287,174,158,158);  // Piirrä neljäkäs
     rotate(60);                    // Pyöräytä kuviota 60 astetta
  }                                 // Lopeta for-silmukka
}                                   // Lopeta draw-lohko

Lähteet ja lisälinkit

P5js-ohjelmointia matematiikan tunnille (Dimension artikkeli 5.4.2019)

Ohjelmointia kouluun etäkerhoillassa (Dimension artikkeli 4.2.2021)

Pe­rus­hah­mo­tus­ta oh­jel­moin­tiin 1: tie­to­ko­ne, oh­jel­moin­ti, al­go­rit­mi (Dimension artikkeli 22.4.2021)

Pe­rus­hah­mo­tus­ta oh­jel­moin­tiin 2: ope­tus, luo­vuus ja har­ras­tus (Dimension artikkeli 14.5.2021)

Pe­rus­hah­mo­tus­ta oh­jel­moin­tiin 3: oh­jaus­ra­ken­teet (Dimension artikkeli 8.6.20221)

Pe­rus­hah­mo­tus­ta oh­jel­moin­tiin 4: oh­jel­moin­ti­tyy­lit, hy­vä oh­jel­mointitapa (Dimension artikkeli 22.6.2021)

Ohjelmointiympäristö: https://editor.p5js.org/

MAOL ry:n julkaisemia ohjeita: https://maol.fi/materiaalit/taidetta-ohjelmoimalla/

Englanninkielisiä ohjeita: https://p5js.org/


Tilaa Dimension uutiskirje – saat sähköpostiisi aina kuunvaihteessa koosteen tuoreimmista artikkeleista

Kirjoittaja