Skip to content

Latest commit

 

History

History
440 lines (379 loc) · 15.2 KB

kokonaisluku.org

File metadata and controls

440 lines (379 loc) · 15.2 KB

Kokonaisluku

Luvun piirtäminen tekstinä piirtoikkunaan

Luku voidaan piirtää tekstinä funktion text() avulla. Tekstin kokoa voidaan muuttaa funktiolla textSize(), ja tekstin sijoittelua suhteessa annettuun kohtaan funktiolla textAlign(). Alla esimerkki.

size (200, 200);
colorMode (HSB, 100);
background (0); // musta tausta
fill (100); // valkoinen teksti

textSize (60); // tekstin koko 30 pikseliä

// tekstin keskikohta piirretään annettuun kohtaan
textAlign (CENTER, CENTER);

text (42, 100, 100);

Kokonaislukumuuttuja ja -vakio

Jos jokin muuttuja tai vakio on kokonaisluku, määrittelyssä käytetään float sanan sijasta sanaa int, joka tulee englannin kielen kokonaislukua tarkoittavasta sanasta integer. Tällöin on syytä muistaa aiemmin esitetyt kokonaislukujen jakolaskun ominaisuudet: kahden kokonaisluvun jakolaskun tulos on aina kokonaisluku.

Tietokoneohjelmassa liukuluku 1.0 ja kokonaisluku 1 eivät välttämättä ole täsmälleen sama luku. Tällä on merkitystä erityisesti silloin, kun lukuja vertaillaan jollain vertailuoperaattoreista ==, !=, >=, <=, > tai <.

{{{example}}}

Piirretään \(1000× 100\)-kokoiseen ikkunaan mustalle taustalle 25 ensimmäistä positiivista kokonaislukua vasemmalta oikealle. Luvut ovat pystysuunnassa piirtoikkunan keskellä. Luku 10 on punainen, muut ovat valkoisia. Lukujen keskipisteiden väli on 30, joka on myös vasemmanpuoleisen luvun \(x\)-koordinaatti. Tekstin koko on 16 pikseliä.

Ohjelmassa muuttuja n on pakko määritellä kokonaislukuna, jotta vertailut kuten n == 10 onnistuvat varmasti.

size (1000, 100);
colorMode (HSB, 100);
background (0); // musta tausta
textSize (16); // tekstin koko

// tekstin keskikohta annetuissa koordinaateissa
textAlign (CENTER, CENTER); 

final float VALI = 30; // tekstin keskipisteiden väli
final float Y = height / 2.0; // tekstin keskipisteen Y-koordinaatti
float x = VALI; // ensimmäisen luvun x-koordinaatti

// piirretään 25 numeroa
for (int n = 1; n <= 25; n += 1, x += VALI) 
{
  if (n == 10)
    fill (0, 100, 100); // punainen teksti
  else
    fill (100); // valkoinen teksti
    
  // luku tekstinä
  text (n, x, Y);
}
<<kokonaisluku-luvut-rivissa>>

Milloin käytetään kokonaislukumuuttujaa tai -vakiota?

Kokonaislukumuuttujaa täytyy käyttää silloin, kun

  • muuttuja saa vain kokonaislukuarvoja ja
  • muuttujaa käytetään myös muuhun kuin piirtokoordinaattien laskemiseen (kuten muuttujan arvon vertaamiseen kokonaislukuun).

Kokonaislukuvakiota täytyy käyttää samanlaisissa tilanteissa.

Liukulukumuuttujaa (tai vakiota) täytyy käyttää silloin, kun muuttuja saa desimaalilukuarvoja.

Muissa tapauksissa ohjelmoija voi valita, haluaako hän käyttää kokonaisluku- vai liukulukumuuttujaa. Kokonaisluvut vievät vähemmän tilaa tietokoneen muistista, ja niillä laskeminen on nopeampaa.

Jakojäännös

Jos n ja m ovat epänegatiivisia kokonaislukuja ja m\(\,≠ 0\), niin Processing-kielen laskutoimitus n % m antaa jakojäännöksen, kun luku n jaetaan luvulla m.

{{{example}}}

size (800, 200);

final float Y = height / 2.0; // tekstin y-koordinaatti

textSize (30);
textAlign (CENTER, CENTER);

text (49 % 9, 100, Y); // jakojäännös, kun 49 jaetaan luvulla 9
text (7 % 5, 200, Y); 
text (5 % 7, 300, Y);
text (0 % 2, 400, Y);
text (1 % 2, 500, Y);
text (2 % 2, 600, Y);
text (3 % 2, 700, Y);

Esimerkin oikeanpuoleisista luvuista huomataan, että kokonaisluvun jakojäännös jaettaessa luvulla 2 on

  • 0, jos luku on parillinen
  • 1, jos luku on pariton.

Muuttujan arvon muuttaminen yhdellä

Koska ohjelmissa joudutaan usein kasvattamaan muuttujan arvoa yhdellä, tätä varten on olemassa erillinen merkintä. Merkintä n++ tarkoittaa samaa kuin n = n + 1.

Vastaavasti merkintä n-- tarkoittaa samaa kuin n = n - 1.

{{{example}}}

Piirretään alla olevan kuvan mukaisesti mustalle taustalle mahdollisimman monta ympyrää piirtoikkunaan. Ympyröiden halkaisija on vakio HALKAISIJA.

size (990, 100);
colorMode (HSB, 100);
background (0); // musta tausta
noStroke (); // ei ympyröiden ääriviivoja

final int HALKAISIJA = 20; // ympyröiden halkaisija (kokonaisluku)
final float Y = height / 2.0; // keskipisteiden y-koordinaatti

// ympyröiden lukumäärä; huom. kokonaisluvun jakaminen kokonaisluvulla
// antaa tuloksena kokonaisluvun: kuinka monta kertaa halkaisija
// mahtuu leveyteen
int ympyroita = width / HALKAISIJA;

for (int n = 1; n <= ympyroita; n++)
{
  if (n % 2 == 1) // ensimmäinen ja muut parittomat sinisellä
    fill (62, 100, 100);
  else
    fill (17, 100, 100);

  ellipse ((n - 0.5) * HALKAISIJA, Y, HALKAISIJA, HALKAISIJA);
}

Alla olevassa ohjelmakoodissa on seuraavia ideoita.

  • HALKAISIJA määritellään kokonaislukuna, jotta kuvaan mahtuvien ympyröiden määrä on helppo laskea kokonaislukujen jakolaskuna width / HALKAISIJA.
  • Ensin lasketaan piirtoikkunaan mahtuvien ympyröiden lukumäärä muuttujaan ympyroita.
  • Ympyrä on sininen piirrettäessä ympyrää, jonka järjestysnumero on pariton.
  • Piirrettävän ympyrän keskipisteen vasemmalla puolella ovat aiemmin piirretyt ympyrät sekä puolet nyt piirrettävän ympyrän halkaisijasta. Niinpä piirrettävän ympyrän keskipisteen \(x\)-koordinaatti on ((n - 0.5) * HALKAISIJA).
<<vakio-siniset-keltaiset-ympyrat>>

{{{example}}}

Piirretään alla oleva sahalaitakuvio piirtoikkunaan, jonka koko on \(400× 400\). Origosta alkavan janan pituus on 10, ja kukin seuraava jana on 10 prosenttia edellistä pidempi. Viivaan voidaan käyttää yhteensä korkeintaan 700 pikseliä. Kulmapisteissä päällekkäin meneviä yksittäisiä pikseleitä ei tarvitse ottaa huomioon.

size (400, 400);

colorMode (HSB, 100);
background (0); // musta tausta
stroke (0, 100, 100); // punaiset viivat

float askelpituus = 10; // seuraavaksi otettavan askeleen pituus
float pikseleitaJaljella = 700; // jäljellä olevien pikselien määrä

float x = 0, y = 0; // viivan kärkipiste, alussa origossa
int n = 1; // otettavan askeleen järjestysnumero

// niin kauan kun pikseleitä on jäljellä riittävästi...
while (pikseleitaJaljella >= askelpituus)
{
  float xSeuraava = x;
  float ySeuraava = y;
  if (n % 2 == 1)
    xSeuraava = xSeuraava + askelpituus;
  else
    ySeuraava = ySeuraava + askelpituus;

  line (x, y, xSeuraava, ySeuraava); // piirretään viiva

  // päivitetään viivan kärkipisteen koordinaatit
  x = xSeuraava;
  y = ySeuraava;

  // vähennetään jäljellä olevien pikseleiden määrää
  pikseleitaJaljella = pikseleitaJaljella - askelpituus;

  askelpituus = 1.1 * askelpituus; // kasvatetaan askelta 10 prosenttia
  n++;
}

Tässä tapauksessa käytän itse mieluummin while- kuin for-silmukkaa. Tällöin while-silmukka korostaa piirtämisen jatkamisen ehtoa.

<<kokonaisluku-sahalaita-pitenevin-askelin>>

Liukuluvun ja kokonaisluvun ero (valinnaista lisätietoa)

Tietokoneessa liukulukujen eli float-tyyppisten muuttujien esitys poikkeaa kokonaislukujen esityksestä. Täten Processing kielen luvut 1 ja 1.0 esitetään tietokoneessa eri lailla, joten ne eivät välttämättä ole täsmälleen yhtä suuria. Niinpä seuraavassa ohjelmassa ei voida taata, että ehto (a == 1) on tosi, vaikka muuttujan a arvo on kolmen desimaalin tarkkuudella 1.000.

size (200, 200);
colorMode (HSB, 100);

float a = 0.1; // muuttujan a arvo alussa

// lisätään 0.1 niin kauan, kun a < 0.99
while (a < 0.99)
  a += 0.1;
// tämän jälkeen muuttujan a arvo lienee 1

if (a == 1) // MUTTA tämä ehto voi olla tosi tai sitten ei
  background (30, 100, 100); // vihreä jos a:n arvo on 1
else
  background (0, 100, 100); // punainen, jos a:n arvo ei ole 1

// piirretään vielä luku a tekstinä kuvan keskelle
fill (0);
textSize (40);
textAlign (CENTER, CENTER);
text (a, width / 2.0, height / 2.0);

Tehtävät

  1. Piirrä alla olevan kuvan mukaisesti 45 neliötä piirtoikkunaan, jonka mitat ovat \(600× 100\). Kunkin neliön sivun pituus on 13.
    size (600, 100);
    
    final int SIVU = 13;
    
    for (int n = 1, x = 0; n <= 45; n++, x += SIVU)
      rect (x, 0, SIVU, SIVU);
        
  2. Piirrä alla olevan kuvan mukaisesti 8 neliötä neliön muotoisen piirtoikkunan lävistäjälle. Kunkin neliön sivun pituus tulee olla kymmenesosa piirtoikkunan leveydestä, ja kuvion tulee skaalautua piirtoikkunan mukana.
    size (400, 400);
    float sivu = width / 10.0;
    
    float k = 0; // piirrettävän neliön koordinaatti (sekä x että y)
    for (int n = 1; n <= 8; n++)
    {
      rect (k, k, sivu, sivu);
      k += sivu;
    }
        
  3. Piirrä \(400× 400\)-kokoisen piirtoikkunan lävistäjälle ensimmäiset 15 positiivista kokonaislukua alla olevan kuvan mukaisesti. Kahden vierekkäisen luvun keskipisteiden \(x\)-koordinaattien väli on 20, samoin kuin \(y\)-koordinaattien väli. Tekstin koko on 16 pikseliä.
    size (400, 400);
    colorMode (HSB, 100);
    background (0);
    fill (100);
    textSize (16);
    textAlign (CENTER, CENTER);
    
    final int VALI = 20;
    
    for (int n = 1, k = VALI; n <= 15; n++, k += VALI)
      text (n, k, k);
        
  4. Piirrä alla oleva kuvio piirtämällä ensin suuri musta ympyrä, sen päälle pienempi valkoinen ympyrä, jonka päälle edelleen pienempi musta ympyrä. Piirtoikkuna on neliön muotoinen, ja kuvan tulee skaalautua piirtoikkunan mukana. Piirretyn ympyrän halkaisija pienenee 10 pikseliä kullakin askeleella.
    size (400, 400);
    colorMode (HSB, 100);
    noStroke ();
    
    // keskipisteen koordinaatti (sekä x että y)
    final float K = width / 2.0; 
    
    int n = 1; // piirrettävän ympyrän järjestysnumero
    for (float halkaisija = width; halkaisija > 0; halkaisija -= 10)
    {
      // lasketaan ympyrän kirkkaus (musta tai valkoinen)
      float kirkkaus;
      if (n % 2 == 1)
        kirkkaus = 0; // parittomat mustia
      else
        kirkkaus = 100;
      fill (kirkkaus);
    
      ellipse (K, K, halkaisija, halkaisija);
      n++;
    }
        
  5. Alla olevassa taulukossa on Processing-lausekkeen n % 3 arvoja muuttujan n eri arvoilla.
    n1234567
    n % 31201201

    Piirrä alla olevan kaltainen kuva \(1000× 100\)-kokoiseen piirtoikkunaan. Suorakulmioita on 95, ja kunkin niistä leveys on 10.

    size (1000, 100);
    colorMode (HSB, 100);
    noStroke ();
    background (0);
    
    final int LEVEYS = 10; // kunkin suorakulmion leveys
    
    for (int n = 1, x = 0; n <= 95; n++, x += LEVEYS)
    {
      // päätellään, millä värillä piirretään
      float varisavy;
      int jakojaannos = n % 3;
      if (jakojaannos == 1)
        varisavy = 0; // punainen
      else if (jakojaannos == 2)
        varisavy = 35; // vihreä
      else
        varisavy = 62; // sininen
      fill (varisavy, 100, 100);
    
      rect (x, 0, LEVEYS, height);
    }
        
  6. Piirrä \(400× 400\)-kokoiseen piirtoikkunaan alla oleva murtoviiva. Viiva alkaa piirtoikkunan keskeltä. Ensimmäisen, piirtoikkunan keskeltä alkavan janan pituus on 5, ja seuraava jana on 20 prosenttia edellistä pidempi. Viivaan voidaan käyttää yhteensä korkeintaan 1500 pikseliä. Kulmapisteissä päällekkäin meneviä yksittäisiä pikseleitä ei tarvitse ottaa huomioon.
    size (400, 400);
    colorMode (HSB, 100);
    background (0);
    stroke (100);
    float x = width / 2.0, y = height / 2.0;
    float pikseleitaJaljella = 1500;
    float askelpituus = 5;
    int n = 1;
    
    while (pikseleitaJaljella >= askelpituus)
    {
      float xSeuraava = x, ySeuraava = y;
      int jakojaannos = n % 4;
      if (jakojaannos == 1)
        ySeuraava = ySeuraava + askelpituus; // alas
      else if (jakojaannos == 2) 
        xSeuraava = xSeuraava + askelpituus; // oikealle
      else if (jakojaannos == 3)
        ySeuraava = ySeuraava - askelpituus; // ylös
      else
        xSeuraava = xSeuraava - askelpituus; // vasemmalle
      
      line (x, y, xSeuraava, ySeuraava);
    
      x = xSeuraava;
      y = ySeuraava;
    
      pikseleitaJaljella = pikseleitaJaljella - askelpituus;
      askelpituus = askelpituus * 1.2;
      n++;
    }
        

Ratkaisuja

  1. <<kokonaisluku-neliot-rivissa>>
        
  2. <<kokonaisluku-neliot-lavistajalla>>
        
  3. <<kokonaisluku-luvut-lavistajalla>>
        
  4. <<kokonaisluku-tikkataulu>>
        
  5. <<kokonaisluku-rgb-palkit>>
        
  6. <<kokonaisluku-laajeneva-spiraali>>