wiki:naloge

Version 65 (modified by Leon Kos, 14 years ago) (diff)

Polepšana oblika izpisa vaje43

Vaje programiranja v jeziku C

Znanje programskega jezika C najlažje pridobimo z vajo. Namen domačih nalog predstavljenih na tej strani je predvsem utrditi določene programske konstrukte, ki se lahko rešijo v krajših programih, katere pravilnost delovanja ni težko preveriti. Naloge se izdelujejo z orodji, ki so predvidene za izdelavo projekta. To pomeni, da je vsako vsako vajo, ki jo izdelujemo najprej preveriti na lokalnem računalniku. Ko je možno izdelati nalogo št. ??? z ukazom

  make vaja???

je vaja??? primerna za shranitev na strežnik, kar naredimo z ukazi svn.

Ker so naloge enostavne, lahko v datoteko Makefile napišemo naslednje implicitne definicije in se s tem izognemo pisanju eksplicitnih ukazov. Dovolj je že če na začetek Makefile napišemo:

CFLAGS = -Wall
LDFLAGS = -lm

in večina nalog bo izdelana z ukazom make vaja???, kjer namesto ?? napišemo številko naloge. Pomembno je, da na strežnik ne shranjujemo izvršnih programov, ki smo jih pridobili s prevajanjem izvorne kode. Če ste programe pomotoma dodali z ukazom npr. svn add vaja12, lahko te datoteke pobrišete z ukazom npr. svn del vaja12. To bo pobrisalo lokalno kopijo in tudi kopijo na strežniku če boste spremembe tudi shranili z ukazom npr. svn ci -m "Briši nepotrebne izvršne programe".

Pravilnost vaših nalog lahko tudi sami preverite z Ocenjevalcem nalog, ki izvede test delovanja s tem da vajo prevede, pregleda izvorno kodo in požene kontrolni test. Pri kontroli delovanja je možno, da ocenjevalec javi daj program ne deluje pravilno. Če pa menite, da Vaš program deluje pravilno, je možno da je kontrolni test napačen ali pa besedilo vaje ni dovolj jasno. V tem primeru odprite Nov Listek in opišite težavo. Če želite odgovor tudi po e-pošti morate vpisati vaš poštni naslov v polje Preferences->Email address:.

Izdelane vaje morajo pravilno delovati, kar preverjamo z Ocenjevalcem nalog. V primeru, da vaja ne prestane testa, ne bo upoštevana kot narejena. Zaželjeno je tudi, da naredimo čim več vaj, ni pa potrebno izdelati več kot je zahtevano.

Prvi dve vaji, ki smo jih naredili v laboratoriju, je potrebno preveriti in morebiti popraviti, da delujeta pravilno.

Vprašanja za utrjevanje

  1. Zakaj je potrebno napisati vrstico #include <stdio.h>
  2. Kako uporabljamo komentarje?
  3. Zakaj je zamikanje stavkov pomembno? Ali prevajalnik upošteva zamikanje?
  4. Koliko decimalk hrani tip int, float in double?
  5. Kakšna je razlika pri prireditvi konstante spremenljivkama c in d
       float c = 3/2;
       float d = 3.0/2;
    
  6. Kaj je funkcija podpičja v stavku? Naštej kje vse ga je potrebno uporabiti.
  7. Koliko je numerična vrednost naslednjega izraza
       int i = 5 < 6;
    
  8. Pod katerimi pogoji naslednja koda izpiše voda? Kako bi jasneje napisali napisane pogojne stavke z uporabo zavitih oklepajev in primernejšega zamikanja?
      if(temp < 0)
        printf("led\n");
      else if (temp < 100)
        printf("voda\n");
      else printf("para\n");
    
  9. Kaj izpiše naslednja koda?
      int x = 3;
      if (x)
         printf("da\n");
      else
         printf("ne\n");
    
  10. Kaj bo izpisala naslednja koda?
      int i;
      for(i = 0; i < 3; i++)
        printf("a\n");
        printf("b\n");
    
      printf("c\n");
    
  11. Koliko elementov vsebuje polje oz. vektor a? Kateri je prvi element? Kateri je zadnji?
      int a[5];
    
  12. Kaj je narobe v naslednjem izvlečku kode?
      int a[5];
      for(i = 1; i <= 5; i = i + 1)
        a[i] = 0;
    
  13. Kateri so štirje pomembni deli funkcije? Katere tri mora klicoči program poznati?
  14. Kakšna je razlika med prefix in postfix operatorjem ++. Kakšna je razlika med naslednjima izrazoma:
      r = i++;
      r = ++i;
    
  15. Kaj je narobe z naslednjim predprocesorskim izrazom?
    #define N 10;
    
  16. Če smo na primer definirali makro
    #define SQR(x) x*x
    

    Zakaj nam potem izraz

    y = 1/SQR(x);
    

    ne deluje pravilno? Kako bi morali pravilno napisati makro SQR(x), da bi delal tudi za izraze

    y = 1/SQR(1-x);
    
  17. Kakšna je razlika v uporabnosti med i in J, ki sta napisana kot
    int i = 10;
    #define J 10
    

    Napotek: Poskusi napisati J = 2 ali int a[i].

  18. Zakaj je potrebno v scanf() argumente za formatnim stavkom pisati z &, pri printf() pa tega ne smemo?
  19. Koliko spomina klic
    malloc(10)
    

    alocira?

    Kaj moramo napisati če želimo alocirati spomin za 10 spremenljivk tipa float?

  20. Kaj mislimo z enakostjo med polji in kazalci v C-ju?
  21. Če je p kazalec, kaj potem pomeni p[i]?
  22. Kako odpiramo datoteko za branje podatkov iz nje? Kaj se spremeni, če bi datoteko želeli odpreti za pisanje?

Uporaba zank in izpis

vaja1

Napiši program, ki zahteva vnos dveh celih številk in nato izpiše njihovo vsoto.

vaja2

Gaussovo kvadratura naj vpraša za meji integriranja funkcije f(x) = 2x4- x3 +1 in rezultat izpiše na zaslon.

vaja3

Izdelaj program ki izpiše naslednje zanke:

for(i = 0; i < 10; i = i + 2)
        printf("%d\n", i);

for(i = 100; i >= 0; i = i - 7)
        printf("%d\n", i);

for(i = 1; i <= 10; i = i + 1)
        printf("%d\n", i);

for(i = 2; i < 100; i = i * 2)
        printf("%d\n", i);

Razjasni si, kako te zanke delujejo in program popravi tako, da bodo v zanki uporabljeni operatorji +=, -=, *=

vaja4

Napiši program ki izpiše ta trikotnik:

        *
        **
        ***
        ****
        *****
        ******
        *******
        ********
        *********
        **********

Ne uporabi desetih printf() ampak uporabi zanko.

for(i = 0; i < 10; i = i + 1)
 {
  /* Več stavkov */
  /* gre lahko tukaj */
 }

vaja5

Izpiši v zanki cela števila od 1 do 10 in njihove kvadrate.

	1	1
	2	4
	3	9
	...
	10	100

vaja6

Stavek for je prav zaprav, okrajšava za stavek while.

Predelaj program, ki izpiše naslednjo zanko:

 for(i = 0; i < 10; i = i + 1)
   printf("i je %d\n", i);

z uporabo stavka while, ki ima naslednjo obliko

  while(pogoj)
  {
    /* vpiši stavek za povečanje števca in izpis */ 
  }

Napotek: V primeru da se nam program obesi v neskončni zanki, ga prekinemo s pritiskom na crtl-C

vaja7

Pretipkaj in poženi naslednji program:

#include <stdio.h>

int main()
{
  int i;

  printf("stavek 1\n");
  printf("stavek 2\n");
  for(i = 0; i < 10; i = i + 1)
   {
        printf("stavek 3\n");
        printf("stavek 4\n");
   }
  printf("stavek 5\n");
  
  return 0;
}

Program ne naredi nič posebnega. Z njim želimo le pojasniti vpliv zavitih oklepajev v zanki in dobiti željen potek programa.

vaja8

Pretipkaj in poženi naslednji program:

#include <stdio.h>

int main()
{
 int i, j;

 printf("začetek programa\n");

 for(i = 0; i < 3; ++i)
  {
        printf("i je %d\n", i);
        for(j = 0; j < 5; j++)
                printf("i je %d, j je %d\n", i, j);
        printf("konec v zanki i = %d\n", i);
  }

 printf("konec programa\n");

 return 0;
}

Tudi ta program ne naredi kaj dosti koristnega. Želi pokazati, kako zanke delujejo in kako jih gnezdimo. V vaji 4 je potrebno uporabiti prikazani način dvojne zanke.

vaja9

Program naj prebere štiri cele številke in izpiše povprečno vrednost kot realno številko.

vaja10

Program naj prebere vrednost x, izračuna kvadrat prebranega števila (x2) in ga izpiše na zaslon. Izdelaj podprogram sqr(x).

vaja11

Program naj prebere vrednost x in n, kot celi števili. Izdelaj podprogram power(x, n), ki izračuna n to potenco števila x in jo izpiše na zaslon.

Pogojni stavek in zahtevnejše zanke

vaja20

Napiši program, ki z zanko in pogojnim stavkom ugotovi, koliko števil od 1 do 10 je večjih od 3 in seveda izpiše rezultat 7.

vaja21

Program naj poleg številk od 1 do 20 izpiše še ali je liha ali soda v obliki

1 je liha
2 je soda
3 je liha
...

Napotek: Uporabi operator %

vaja22

Izdelaj program, ki izpiše v katero smer se je 2D točka največ premaknila, glede na koordinatno izhodišče. Možni odgovori so:

  • levo
  • desno
  • gor
  • dol

Za prebrano točko 2 1 bo program odgovoril desno.

vaja23

Tako kot v vaji 22 naj dodatno še izpiše v kater smer se je premaknila. S tem da se najprej izpiše večji pomik in nato manjši. Za prebrano točko 2 1 bo program odgovoril desno gor.

vaja24

Napiši program, ki izpiše prvih 7 pozitivnih števil in njihovo faktorielo (fakulteto). (Faktoriela 1 je 1, faktoriela 2 je 1*2=2, faktoriela 3 je 1 * 2 * 3 = 6, faktoriela 4 je 1 * 2 * 3 * 4 = 24, itd.)

vaja25

Program naj izračuna prvih 30 Fibonaccijevih števil. Vsaka Fibonaccijeva številka je vsota prejšnjih dveh števil F(n) = F(n-1) + F(n-2), F(0) = 1, F(1) = 1. Izpis naj bo v obliki:

 1 + 1 = 2
 1 + 2 = 3
 2 + 3 = 5
 3 + 5 = 8
 5 + 8 = 13
...

vaja26

Napiši program ji za podano število izpiše je praštevilo ali ni praštevilo. Práštevílo je naravno število n > 1, če ima natanko dva pozitivna delitelja (faktorja), število 1 in samega sebe kot edini prafaktor.

vaja27

Pohitri vaja26 z dejstvom, da razen 2 nobeno sodo število ni praštevilo. Glej vaja21.

vaja28

Napiši program, ki tabelira poštevanko od 1 do 10, tako da izpiše vse skupaj v 10 vrsticah v obliki:

1*1=1 1*2=2 1*3=3
...
10*1=1 10*2=20 ...

vaja29

Za dan vektor B[7] uredi števila po velikosti od najmanjšega do največjega in jih zapiši v vekotor v naslednji obliki -> B[min]...B[max]. S pomočjo for zanke izpiši vrednosti urejenega vektorja B na zaslon.

  float B[7] = {3.3, -23.2, -4.5, 56.0, 45.5, 69.9, 40.5};

vaja30

Za matriko A[25] podano v vaja46 določi mesto maksimalnega števila in vrednost elementa izpiši na zaslon.

vaja31

Na zaslon izpiši Pascal-ov trikotnik (Pascal's triangle) za 8 vrstic v spodaj prikazani obliki.

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

1 5 10 10 5 1

1 6 15 20 15 6 1

1 7 21 35 35 21 7 1

Nizi, vektorji, matrike

vaja40

Program iz vaje 28 priredi tako, da bo se zmnožek najprej predizračunal v polje

int a[100];

in nato naj program vpraša za dve števili, ter izpiše rezultat, ki ga vzame iz polja a[].

vaja41

Napiši program ki bo v polje števil nadomesitil z njihovnimi kvadrati. Program naj vpraša kateri indeks iz polja želimo in naj izpiše vrednost v polju. S stavkom if mora tudi kontrolirati meje indeksov.

  int a[] = {1, 2, 9, 33, 22, 11, 3, 4, 3, 55, 
             66, 33, 22, 22, 33, 54, 5, 6, 7, 
             8, 223, 34};

vaja42

Za podano kvadratno matriko a[16] in vektor x[4]

float a[16] = {1, 2, 3, 4,
               0, 1, 2, 3,
               2, 3, 4, 5,
               3, 2, 2, 1};
float x[4], b[4];

napiši program, ki prebere štiri vrednosti in izpiše zmnožek matrike in vektorja s stavkom

printf("%.1f %.1f %.1f %.1f\n", b[0], b[1], b[2], b[3]);

vaja43

Program naj prebere datoteko. Prvo število je n, drugo število je št. delitev div, nato pa prva dva stolpca sta x in y točke p0, druga dva stolpca sta (x1, y1) točke p1, ter zadnji stolpec je pretok q.

8 1
00 00 06 00 0
06 00 14 00 -1
14 00 20 00 0
20 00 20 10 0
20 10 14 10 0
14 10 06 10 1
06 10 00 10 0
00 10 00 00 0

Datoteko preberite v spremenljivke

#define MAXN 100
float p0[MAXN*2], p1[MAXN*2], q[MAXN];
int n, div;

in vsako vrstico v zanki izpišite z naslednjim formatnim stavkom:

   printf("%4.1f %4.1f %4.1f %4.1f %4.1f\n", ...

prve in druge točke elementa ter q.

vaja44

Za podano kvadratno matriko A[] zmanjšaj diagonalne elemente za vrednost 1 in spremenjene diagonalne elemente matrike A s pomočjo for zanke izpiši na zaslon .

float A[25] =   {3, 5, 90, 2 ,1, 
                 1, 71, 59, 5, 5, 
                 1, 2, 3, 54, 2, 
                 12, 56, 32, 11, 1, 
                 34, 56, 78, 45, 12
                 }; 

vaja45

Polje a[] iz vaje 41 prepišite v matriko float b[] velikost 8x3. S tem sa so elementi, ki manjkajo postavljeni na 0. Vrstice izpišite na eno decimalko natančno.

vaja46

Za podano kvadratno matriko A[25] zmanjšaj diagonalne elemente za vrednost 1.1, prepiši enodimenzionalno polje A v dvodimenzionalno polje B, ki ga računamo kot matriko 5x5 izpišemo z dvojno zanko na zaslon.

  float A[25] = {3.3, 5.2, 90.5, 2.3 ,1.1,
                   1.9, 71.0, 59.5, 5.3, 5.5,
                   1.0, 2.2, 3.5, 54.3, 2.2,
                   12.4, 56.1, 32.2, 11.4, 1.6,
                   34.8, 56.4, 78.9, 45.3, 12.3
                   };

vaja47

Za izračun Pascal-ovega trikotnika (glej vaja31) uporabi podprogram pascals_triangle(n), kjer je n=8. Vsako vrstico Pascal-ovega trikotnika zapiši v vrstico matrike P[64]. Prazna mesta matrike postavi na vrednost 0. Izpiši matriko na zaslon (Uporabi for zanko). Primer izgleda izpisa ene vrstice:

  printf("%d %d %d %d %d %d %d %d\n", P[0], P[1], P[2], P[3], P[4], P[5], P[6], P[7], P[8]);

Podprogrami

vaja60

Predelajte program za množenje matrike z vektorjem iz vaje 42, tako da boste pred izpisom uporabili klic podprograma s stavkom

   mat_vec4(b, a, x);
   printf("%.1f %.1f %.1f %.1f\n", b[0], b[1], b[2], b[3]);

vaja61

Predelajte program vaje4 tako, da boste napisali podprogram, ki ga boste klicali v naslednji zanki

  for(i = 0; i < 10; i++)
    print_stars(i);

vaja62

Napišite podprogram float celsius(float fahrenheit), ki pretvori Fahrenheitove stopinje v Celsiusove. Formula za pretvorbo je °C = 5/9 * (°F - 32). Program naj naprej vpraša za stopinje F in nato na decimalko natačno izpiše vrednost v Celzija. Zapomnite si, da celoštevilčni izraz 5/9 da rezultat 0, zato ne smete uporabiti celoštevilčnega deljenja.

vaja63

Stavek r = rand()*N/RAND_MAX + 1 vrne naključno številko med 1 in N. Izdelajte program, ki simulira metanje kocke. Izdelajte program, ki simulira zaporedno metanje dveh kock in izriše histogram za 100 metov v (približno) taki obliki:

2: 2    **
3: 5    *****
4: 4    ****
5: 10   **********
6: 15   ***************
7: 28   ****************************
8: 12   ************
9: 9    *********
10: 7   *******
11: 5   *****
12: 3   ***

Prva številka pomeni vsoto pik na obeh kockah, druga številka pa pomeni koliko krat se je dogodek zgodil, kar je tudi grafično narisano z podprogramom iz vaje 23.

Napotek: Pogled v navodila za funkcijo rand vam bo razkril, da je potrebno vklučiti header <stdlib.h> in povezovati z -lc.

vaja64

Izdelajte podprogram za linearno interpolacijo. Program naj vpraša za dve točki (x0,y0) in (x1,y1) ter mesto na osi x za katero želimo vrednost y. Npr. za

0 0 
1 1 
0.5

mora vrniti 0.5.

Podprogram naj ima naslednji prototip:

  float linear_interpolation(float x, float p0[2], float p1[2])

vaja65

Podprogram za parametrizacijo daljice naj izpiše koordinato glede na parameter t, ki je v mejah od 0 do 1. Podobno kot pri vaji 64 preberemo točki (x0,y0) in (x1,y1) in parameter t. Prototip

  void linear_interpolation(float t, float p0[2], float p1[2])

naj izpiše točko s formatom "%.1f %.1f". Prednost parametrične interpolacije je v tem, da deluje tudi za navpično daljico. Npr.

0 0
0 2
0.5

vrne 0.0 1.0

Ko je parameter t=0 se izpiše začetna točka. Pri t=1 pa končna.

vaja66

Podobno kot v vaji 65 izdelajte podprogram, ki za parameter t v mejah od -1 do 1 izpiše točko med podanima točkama. Ko je parameter t=-1 se izpiše začetna točka. Pri t=1 pa končna. Za t=0 se izpiše točka na sredini.

vaja67

Napiši podprogram decToBin(x), ki poljubno vrednost celega števila x prebranega iz zaslona pretvori v binarni zapis in vrednost izpiše na zaslon. Primer:

25:2
121
60
30
11
01

Ostanke deljenja decimalnega števila izračunanega po zgornjem primeru preberemo v nasprotnem vrstnem redu. Za zgornji primer dec: 25 -> bin: 11001. Uporabi operator %. (Primer: 25%2 = 1)!

Dinamična alokacija spomina in delo z datotekami

vaja80

Program naj prebere datoteko vaja80.dat, ki vsebuje seznam celih številk in izpiše njihovo vsoto. V prvi vrstici je število celih števil ki sledijo v naslednjih vrsticah. Primer:

4
13
23
21
11

Za ta primer mora program izpisati 72. Število vrstic v datoteki vaja80.dat je lahko največ 100.

vaja81

Podobno kot v vaji 80 preberite datoteko vaja81.dat s tem da števila niso več omejena z velikostjo polja ampak ga dinamično alocirajte z malloc() po tem, ko bo prebrana prva vrstica.

vaja82

Preberi datoteko vaja82.dat v kateri sta zaporedno zapisani dve 4x4 matriki. Na primer:

1 2 3 4
5 6 7 8
9 0 1 1
1 2 2 2
1 1 1 1
1 1 1 1
1 2 5 6
3 4 5 2

Program naj prebere datoteko v dve matriki in nato sešteje obe matriki v novo matriko (matrike seštevamo po elementih). Ko imamo novo matriko naj program vpraša kateri element matrike želimo izpisati in sicer i-to vrstico in j-ti stolpec (npr. i=1 in j=3 -> 9) in element i,j izpiše na zaslon.

vaja83

Program naj prebere iz datoteke vaja83.dat matriko velikosti ixj in izpiše element {2, 3}. Format datoteke je

4 5
1 2 3 4 5
4 5 5 6 6
4 4 4 99 4
6 7 7 8 1

V prvi vrstici piše število vrstic in število kolon matrike. Izpisal pa bi 99.

vaja84

Matriko iz tako kot pri vaji 83 preberemo iz datoteke vaja84.dat in izpišemo v transponirani obliki kot cela števila. Matriko celih števil dinamično alocirajte z malloc.

vaja85

Matriko iz tako kot pri vaji 83 preberemo iz datoteke vaja85.dat in Vse elemente matrike kvadriramo in zapišemo v datoteko vaja85.rez, v istem formatu celih števil.

Aplikacije

vaja100

Izračunaj faktor Učinkovite Rabe Energije, tako kot ga podaja Elektro Ljubljana. Dobavitelj v ceniku za vsak razred porabe določi faktor cene energije, ki je osnova za izračun faktorja URE po naslednji enačbi:

URE = ∑(Ei FCE i)/Epovprečna dnevna poraba

Tabela razredov porabe in pripadajočimi faktorji cene električne energije] ima 5 razredov s progresivno stopnjo FCE

Razred porabePovprečna dnevna poraba energije (Ei)Faktor cene energije (FCE)
1.razreddo 6 kWh dnevne porabe1.0
2.razrednad 6 do vključno 12 kWh dnevne porabe1.1
3.razrednad 12 do vključno 18 kWh dnevne porabe1.3
4.razrednad 18 do vključno 24 kWh dnevne porabe1.5
5.razrednad 24 kWh dnevne porabe2.0

Na primer URE za 8kWh dnevne porabe izračunamo kot URE=(6*1.0-(8-6)*1.1)/8

TabelaURE Faktorjev učinkovite rabe energije za posamezno povprečno dnevno porabo, se računajo samo za celoštevilčni del povprečne dnevne porabe. Izdelaj program, ki za vnešeno realno povprečno porabo izpiše faktor URE v formatu, kot je v pred izračunani tabeli.

Napotek: Za izračun celega dela realnega števila uporabite funkcijo floor.

vaja101

Ceno za uporabo omrežij določa Akt o določitvi metodologije za obračunavanje omrežnine in metodologije za določitev omrežnine in kriterijih za ugotavljanje upravičenih stroškov za elektroenergetska omrežja, (Ur.l. RS 121/2005) in je sestavljena iz:

  • stalnega mesečnega prispevka za moč, ki zanaša 0,66179 €/kW/mesec
  • cene za prenešeno delovno energijo, ki znaša:
    • v primeru dvotarifnega načina merjenja porabe električne energije:
      VT: 0,03731 €/kWh
      MT: 0,02924 €/kWh
      
    • v primeru enotarifnega načina merjenja porabe električne energije:
      ET:  0,03462 €/kWh
      

Izdelaj program, ki uporabnik vpraša po predvidenem mesečnem številu kWh VT in NT in izpiše ceno za prenešeno delovno energijo v primeru dvotarifnega in v primeru enotarfnega načina merjenja porabe električne energije. Uporabniku naj glede na vnešena podatka program svetuje, kateri način je zanj najbolj primeren.

vaja102

Če ste izdelali vajo 100 in 101, potem združite programa v vaji 102 tako, da izračunate kako bo z elektriko po novem sistemu z URE faktorjem.

Obračun porabljene električne energije na podlagi izračunanega faktorja URE se izvede tako, da se pomnoži količina električne energije v posamezni tarifi, s ceno električne energije v tej tarifi in z izračunanim odjemalčefim faktorjem URE. Upoštevajte, da ima mesec 31 dni. Program pa naj tako kot v vaji 11 vpraša za število kWh v visoki in nizki tarifi, izpiše posamezne cene ter svetuje najprimernejši način tarifiranja.

Grafični jezik OpenGL

Vse naloge v nadaljevanju so zastavljene tako, da se želi grafični izris z določenimi primitivi in v določeni obliki. Če ni podrobneje določeno, je potrebno pripraviti izris tako, da je dovolj ličen in v ustreznem razmerju z velikostjo okna. Okno naj bo velikosti 400x400. Za spremembo koordinatnega sistema modela je potrebno uporabiti transformacijske funkcije v ustreznem vrstnem redu. Transformacijske funkcije so:

  • translacija
    void glTranslatef( GLfloat x,   GLfloat y, GLfloat z )
    
  • skaliranje
    void glScalef( GLfloat x, GLfloat y, GLfloat z )
    
  • rotacija
    void glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
    

vaja120

Program, ki bere podatke robnih elementov iz datoteke

8 1
00 00 06 00 0
06 00 14 00 -1
14 00 20 00 0
20 00 20 10 0
20 10 14 10 0
14 10 06 10 1
06 10 00 10 0
00 10 00 00 0

tako, da bo na vozlišča elementov postavil rdečo kroglo velikosti 1.0, na sredino robnih elementov pa zeleno kroglo velikosti 0.5. Za izris krogle uporabite

void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);

z osmimi delitvami po dolžini in širini krogle.

V prikazani datoteki v prvi vrstici piše število elementov 8 in število delitev 1. V naslednjih vrsticah so koordinate robnih elementov v ravnini in jakost vtoka. Vsaka vrstica ima naslednje koordinate

x1 y1 x2 y1 q

vaja121

Tako kot v vaji 120 preberite datoteko robih elementov in na sredini vsakega elementa pravokotno na element narišite puščico vtoka ali iztoka v element. Velikost puščice naj bo sorazmerna velikosti pretoka. Če pretoka ni, se puščice ne riše. Puščica pritoka naj bo zelen, puščica odtoka pa rdeče barve.

vaja122

Tako kot 120 naj se izriše sistem robnih elementov. V prvem kvadrantu pa naj se kot podlaga izriše še mreža točk (grid) v obsegu [0..10] z gostoto 1.0

Za risanje točk uporabite primitiv GL_POINTS v sivi barvi glColorf(0.5, 0.5, 0.5);

Spodnja leva točka sistema mora sovpadati z izhodiščem prvega kvadranata.

vaja123

Program naj vpraša za rotacijo okoli osi x, y in z ter nato nariše koordinatni sistem kot tri vektorje dolžine 1.0 v rdeči, zeleni in modri barvi. Na koncu naj bo še prostorska puščica primerne velikosti (npr 0.15) izdelana s stožcem za kar lahko izdelamo z

void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);

vaja124

Narišite kocko v izometrični projekciji z dolžino stranice a = 3. Vozlišča povežite med seboj s črtami in v vsako vozlišče postavite rumeno kroglo velikosti 0.5. Za izris črt uporabite primitiv

  glBegin(GL_LINES)
  /// ...
  glEnd();

vaja 125

Napišite program, ki bo za vrednost n = 1 do 7 zračunal n!. Vrednosti n naj bodo na osi x, n! pa na osi y. Točke (x, y) za posamezno vrednost poveži skupaj z uporabo primitiva

  glBegin(GL_LINE_STRIP)
  /// ...
  glEnd();

vaja 126

Datoteka vaja126.dat:

3
00
21
-12

Iz datoteke preberi tri točke p1, p2 in p3. Z vektorskim produktom med vektorjema vec(a)=p2-p1 in vec(b)=p3-p1 ustvari nov vektor vec(c), ki bo določal mesto točke p4 (s puščicami prikažite smer vektorjev a, b in c). Vse točke povežite med sabo in v novo določeno točko p4 vstavite čajnik za kar uporabite:

   glutWireTeapot(0.5);

vaja 127

Narišite 2D koordinatni sistem, katerega izhodišče se bo nahajalo v sredini zaslona (x os naj bo rdeče, y os pa zelene barve). V vsakem kvadrantu koordinatnega sistema nariši mrežo točk v obsegu [0..10] z gostoto (Kvadrant: K1[0.5], K2[1.0], K3[0.5], K4[1.0]). Vsak kvadrant naj ima mrežne točke drugačne barve (K1-zelene, K2-modre, K3-sive in K4-bele) izdelane s primitivom

   glBegin(GL_POINTS);
   ///....
   glEnd();

vaja128

Narišite sinusno krivuljo v razponu od -π do π. Število točk naj bo možno spremeniti s konstanto N, izris pa izvedemo z GL_LINE_STRIP.

#define N 50

vaja129

V eneom od prejšnih vajah uporabite naslednji podprogram in ga prijavi kot GLUT podprogram, ki se izvede pri spremembi velikosti okna.

void reshape(int w, int h)
{
  GLdouble width = w, height = h;
  GLdouble left, right, bottom, top, znear, zfar;

  if (w > h)
    {
      left = -width/height;
      right = width/height;
      bottom = -1.0;
      top = 1.0;
    }
  else
    {
      left = -1.0;
      right = 1.0;
      bottom = -height/width;
      top = height/width;
    }
  znear = -1.0;
  zfar = 1.0;
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(left, right, bottom, top, znear, zfar);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

Kakšna je lastnost take spremembe okna? Začetno okno izrišite v velikosti 500x300.

vaja130

Izrišite trikotnik s prelivanjem osnovnih barv v vozliščih. Za osnovo naj vam bo naslednji fortranski program:

subroutine display
implicit none
include GL/fgl.h
call fglClear(GL_COLOR_BUFFER_BIT)
call fglBegin(GL_TRIANGLES)
call fglColor3f(1.0, 0.0, 0.0)
call fglVertex2f(-1.0, -1.0)
call fglColor3f(0.0, 1.0, 0.0)
call fglVertex2f(0.0, 1.0)
call fglColor3f(0.0, 0.0, 1.0)
call fglVertex2f(1.0, 0.0)
call fglEnd
call fglFlush
end

vaja131

Izrišite kocko v prostoru tako, da uporabite podprogram, ki izrisuje kvadrate različnih barv s funkcijo

void glRectf( GLfloat x1, GLfloat y1, GLfloat x2,  GLfloat y2 );

Funkcija glRectf riše v ravnini z=0. Z uporabo matričnih transformacij pa lahko rišemo v poljubni ravini. Za osnovo naj vam bo naslednji fortarnski program:

subroutine kvadrat(i)
real r(6), g(6), b(6)
data r /1,0,0,1,1,1/, g /0,1,0,1,0,0/
data b /0,0,1,0,1,1/
call fglPushMatrix
call fglColor3f(r(i), g(i), b(i))
call fglTranslatef(0.0, 0.0, 1.0)
call fglRectf(-1.0, -1.0, 1.0, 1.0)
call fglPopMatrix
end
subroutine display
implicit none
include GL/fgl.h
call fglClear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT)
call fglPushMatrix
call fglRotatef(30.0, 1.0, 0.0, 0.0)
call fglRotatef(30.0, 0.0, 1.0, 0.0)
call fglScalef(0.5, 0.5, 0.5)
call kvadrat(1)
call fglRotatef(90.0, 0.0, 1.0, 0.0)
call kvadrat(2)
call fglRotatef(90.0, 0.0, 1.0, 0.0)
call kvadrat(3)
call fglRotatef(90.0, 0.0, 1.0, 0.0)
call kvadrat(4)
call fglRotatef(90.0, 1.0, 0.0, 0.0)
call kvadrat(5)
call fglRotatef(180.0, 1.0, 0.0, 0.0)
call kvadrat(6)
call fglPopMatrix
call fglFlush
end

Pri izbiri okna morate vklopiti globinski pomnilnik z

glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
glEnable(GL DEPTH TEST);

vaja132

Tako kot v nalogi 130 izrišite prelivajoč se trikotnik s tem da prijavite še naslednjo funkcijo pri izrisu okna velikosti 500x300:

void reshape (intw, inth) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D (0.0, w, 0.0, h);
}

vaja133

Izrišite naslednji mnogokotnik v oknu velikosti 300x300 tako, da bo z leve in desne strani okoli 20% praznega prostora. Če želite ga lahko tudi pobarvate.

glBegin(GL_POLYGON);
glVertex2f(0.0, 0.0);
glVertex2f(0.0, 3.0);
glVertex2f(4.0, 3.0);
glVertex2f(6.0, 1.5);
glVertex2f(4.0, 0.0);
glEnd();

vaja134

Kocko iz vaje 124 rišite z gladkimi črtami debeline 1.5, za kar uporabite naslednja ukaza v glavnem programu:

glEnable(GL_LINE_SMOOTH); 
glLineWidth(1.5);