Tapaus 5 - Tietokonegrafiikka ja vuorovaikutus

Tässä tapauksessa tutustutaan ruudulle piirtämisen alkeisiin. Lisäksi jatketaan kierroksella 0 aloitetusta tiedon syöttämisestä tietokoneelle. Tällä kertaa fokuksena on syötteen ja tietokoneohjelman vuorovaikutus.

Virike:

Yksinkertainen näytölle piirtäminen

Tapauksessa 3 tutustuttiin hiukan vektorigrafiikkaan, mistä tällä kertaa jatketaan hiukan pidemmälle konkretiaan. Vektorigrafiikassa kuva muodostuu erilaisten matemaattisten funktioiden määrittämistä muodoista ja niiden rajaamista alueista. Esimerkiksi lumiukon saa piirrettyä seuraavalla koodinpätkällä:

Lumiukko.
Vasemmanpuoleisella koodilla piirretty lumiukko.
import java.awt.Color
import java.awt.Dimension
import java.awt.Graphics2D

import scala.swing.SimpleSwingApplication
import scala.swing.MainFrame
import scala.swing.Panel

object SnowMan extends SimpleSwingApplication {

  def top = new MainFrame {
    contents = new PaintPanel()
  }
}

class PaintPanel extends Panel {
  override def paintComponent(g: Graphics2D) : Unit = {
    g.setColor(Color.WHITE) // body
    g.fillOval(15, 0, 40, 40)
    g.fillOval(10, 40, 50, 50)
    g.fillOval(0, 90, 70, 70)
    g.setColor(Color.BLACK) // eyes
    g.drawOval(25, 15, 5, 5)
    g.drawOval(40, 15, 5, 5)
    g.setColor(Color.ORANGE) // nose
    g.drawPolyline(Array(35, 48, 35, 35), Array(23, 25, 27, 23), 4)
  }
}

"fill"-alkuiset metodit täyttävät piirtämänsä muodon määrätyn väriseksi kun taas "draw"-alkuiset metodit ainoastaan piirtävät ääriviivat. Metodeissa objektin sijainti määräytyy aina vasemman ylänurkan perusteella, ja tätä voi pitää sääntönä muussakin tietokonegrafiikassa. Käytettyjen fill- ja draw-metodien kaksi ensimmäistä parametria määrittävät x- ja y-koordinaatit ja kaksi seuraavaa aluetta rajoittavan naliön leveyden ja korkeuden. Hiukan erikoisempi monikulmion piirtämiseen tarkoitettu metodi ottaa parametreikseen x- ja y-koordinaatit listoina ja pisteiden yhteislukeman. Loppuihin Graphics-luokan metodeihin voit tutustua luokan dokumentaatiosta: http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html

Tässä oli vain lyhyt esittely Graphics2D-luokkaan, mutta todellisuus on paljon laajempi sisältäen luokat fonttien ja kuvien esittämiseen.

Vuorovaikutteisuus tietokoneohjelmissa

Ohjelmoinnissa vuorovaikutus esimerkiksi hiiren ja ohjelman välillä aikaansaadaan kuuntelemalla hiiren liikkeitä ja klikkauksia ohjelmassa. Kuten aivan ensimmäisellä kierroksella (0) saatettiin oppia, näppäimistön painallukset aiheuttavat signaalin tai tapahtuman. Scalassa jokainen käyttöliittymäkomponentti on samalla kuuntelija, jonka avulla tapahtumiin on helppo varautua. Esimerkiksi kierroksella kolme tarjotussa käyttöliittymässä, nappeihin lisättiin toiminnallisuus seuraavasti:

reactions += {
  case ButtonClicked(b) =>
    for (x <- buttons if x._1 == b) { // "buttons" array holds pixelfilter buttons
      img = pixel_filter.applyFilter(img, x._2)
    }
    if (!buttons_f.isEmpty) { // "buttons_f" array holds fourierfilter buttons
      for (x <- buttons_f if x._1 == b) {
        img = fourier_filter.applyFilter(img, x._2)
    }
  }
  icon.setImage(img)
  this.repaint()
}

Tämän alustuksen ohella kannattaa tutustua Ohjelmointi 1-kurssin materiaalin vastaavaan osioon osoitteessa: https://greengoblin.cs.hut.fi/o1_s2013/course/k11/osa01.html.

Kuvitellaanpa seuraavaksi tilanne, jossa olette suunnittelemassa yhdessä piirto-ohjelmaa, jossa on mahdollisuus vaihtaa erilaisia työkaluja käyttöön, säätää väriä, tallentaa ja avata kuvatiedostoja (referenssinä voi käyttää MS:n Paint-ohjelmaa). Hahmotelkaa tarvitsemianne luokkia, niiden välistä kommunikaatiota (palauttakaa meileen viime kierroksen MVC-malli), sekä pohtikaa millaista interaktiota luokkien välillä tulisi olla. Toisin sanoen mitkä luokista olisivat tapahtumien aiheuttajia (Publisher) ja missä luokissa tapahtumat käsiteltäisiin (eli mitkä luokat kuuntelijoita).

Mahdollisia oppimistavoitteita

Työotsake:
Oppimistavoitteet: