TOPIC D: Procedures.

Contents

PROCEDURE

Exercises


T1: SumDivisibleBy.

Wat is de output van het volgend programma?
Voer het uit met de debugger! Hier is de documentatie (vind je in het menu onder Documentation => XDS manual). Bemerk het verschil tussen F7 en CTRL-F7.

MODULE T1;
<* NOOPTIMIZE + *>
<* WOFF + *> (* geen warnings *)
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdReal, WrReal,
WrFixReal, RdBool, WrBool;
    FROM RealMath IMPORT power, arctan, pi, cos, sin, sqrt;

    PROCEDURE IsSumDivisibleBy(x1, x2, x3: INTEGER): BOOLEAN;
      VAR result: BOOLEAN;
    BEGIN
      IF ((x1 + x2) MOD x3) = 0 THEN
        result := TRUE;
      ELSE
        result := FALSE;
      END;
      RETURN result;
    END IsSumDivisibleBy;    
  VAR opl: BOOLEAN;

      a, b, c: INTEGER;
BEGIN
    WrLn;
    opl := IsSumDivisibleBy(10, 6, 4);

    WrBool(opl, 0); WrLn;
    a := 5;
    b := 3;
    c := 3;
    opl := IsSumDivisibleBy(a, b+c, c);
    WrBool(opl, 0); WrLn;
END T1.


S1: Procedure definities

A. Schrijf de header ('eerste lijn') voor de volgende procedures. Schrijf ook op 1 lijn een voorbeeld waarin je de procedure gebruikt (bvb y := MyProcedure(x); ).
  1. Een procedure die een cirkel tekent met een gegeven middelpunt en straal.
  2. Een procedure die kijkt of een getal deelbaar is door een ander.
  3. Een procedure die een geheel getal op het scherm schrijft.
  4. Een procedure die de preciese afstand tussen 2 punten berekent.
        B. Implementeer deze laatste procedure.

 


S2: Piramides

Start met dit . Hier is de code van de JJ3D 3D engine. Zie ook de documentatie over JJ3D.
  1. Maak een procedure die een piramide tekent met een bepaalde hoogte en als grondvlak een vierkant in het XY-vlak.
  2. Teken 50 piramides op een lijn evenwijdig met de X-as, één piramide om de 30 pixels. Neem als hoogte 300.
  3. Neem nu als hoogte 300 × de sinus-functie waarbij je de x als de hoek in graden neemt.
  4. Maak er een animatie van. Elke piramide wordt om de beurten getekend, van links naar rechts. In topic B zagen we een voorbeeld van animatie.

S3: Zuilen

  1. Teken een zuil door 5 cilinders met een verschillende kleur op elkaar te stapelen en er een blok op te zetten.
  2. Maak een procedure die een zuil op bepaalde positie met een bepaalde radius en hoogte. Zet de code erin. De grootte van de cilinders bepaal je adhv de totale hoogte van de zuil
  3. Teken een rij van 8 zuilen in de Y-richting.
  4. Teken 2 van die rijen naast elkaar, zet er een dak op en je hebt een tempel. 
  5. Zet deze code in een procedure die een tempel van een zekere hoogte tekent op een bepaalde positie



S4: Procedure definities

Schrijf de header ('eerste lijn') voor de volgende procedures. Schrijf ook op 1 lijn een voorbeeld waarin je de procedure gebruikt (bvb WrCard(x, 0); ).
  1.  Een procedure die een kabelbrug tekent zoals in S6 van Topic A.
  2.  Een procedure die de gemiddelde afstand van een aantal punten tot de oorsprong berekent. De coordinaten van de punten worden met behulp van arrays meegegeven (in deze oefening zie je een voorbeeld van zulke arrays).
  3.  Een procedure die een deel van een circel tekent (een 'taartpunt'), van 1 hoek tot een andere.




S5: Van cilinder tot koeltoren

Start met deze code om punten van een cirkel op te slaan (ook reeds gebruikt in oefening S3 van Topic C). Zie ook de documentatie over JJ3D.
  1. Vul 2 arrays met de punten van 1 cirkel, 1 array voor de x-coördinaten en 1 voor de y-coördinaten. Teken met behulp van deze arrays 2 cirkels evenwijdig met het XY-vlak: 1 op hoogte 0 en een op hoogte 400.
  2. Verbind de punten van de 2 cirkels. Zo bekom je een cilinder.
  3. Gebruik een shift-parameter s om punt i van cirkel 1 met punt i+s te verbinden. Dan bekom je een koeltoren.
  4. Teken in een animatie kerncentrales met oplopende shift-parameter:je  s=0 (dan wordt er een cilinder getoond) - even wachten - s=1 tot s = NBR (je mag NBR heel hoog zetten)

 


S6: Hexagons

  • Maak een procedure die een hexagon in 2D tekent met gegeven middelpunt en straal. Teken 1 hexagon in het midden van je scherm. Start met .
     
    2. Gebruik de procedure om een rij van hexagons te tekenen.
    3. Optioneel: teken een 'stapel' van hexagons.



    H1: Kubus



      Maak een procedure die een Kubus tekent met gegeven middelpunt, de grootte S en de kleur.

      Je kan bijvoorbeeld gebruik maken van de Rectangle procedure en Line procedure uit de gekende Graph library.


    H2: Toren bouwen.

    Start met deze code en voeg je procedure uit de vorige oefening toe.

  • We wensen een toren van 2.5m te bouwen door het opstapelen van kubussen.
  • De onderste kubus heeft een ribbe van 1m, de volgende kubussen zijn telkens 2/3 kleiner.
  • opgelet: als je 1m als CARDINAL schrijft, in centimeters bvb, dan geeft  2/3*...  problemen, immers wordt 2/3 = 0.666 afgerond tot 0 (is immers een cardinal). Beter doe je daarom ...*2/3. Ambetante Modula Toch.
  • Stapel de kubussen opeen tot je toren net hoger is dan 2.5m.
  • tip: bereken telkens opnieuw de 'grond' voor de volgende kubus en de nieuwe grootte.
  • Teken de kubussen mbv de Kubus procedure van de vorige oefening. Neem 1meter = 100 pixels. In de startcode hebben we de 'grond' op y=400 getekend.
  • Hoeveel kubussen heb je nodig? Print de waarde.

  •  

    H3: Lopend Manneke.

    Start met de code van  .
    Gegeven is een procedure om een ledemaat te tekenen is gegeven (parameters x,y zijn de coordinaten van het begin van de ledemaat, het aanhechtingspunt aan het lijf).
    Gevraagd:
    1. Teken een manneke met 2 benen.
    2. Zet deze code dan in een procedure om een manneke te tekenen (eigenschappen: positie, grootte, hoek van benen, kleur)
    3. Teken dan het manneke en laat het zich vooruit lopen door de benen 'correct' te bewegen.
    4. Zorg dat het manneke links weer verschijnt als het rechts van het scherm verdwijnt (let wel op dat je niet links buiten het scherm tekent, voor negatieve waarden crasht je programma)
    5. Zorg dat je de snelheid van het manneke kan regelen:
    6. Als het manneke aan het einde van het scherm komt, moet hij terugkeren. Gebruik hiervoor de naarLinks boolean die de richting van de voetjes aangeeft.
    7. Het programma moet stoppen als je op 'x' duwt.
    Uitbreidingen: teken er bewegende armpjes bij, laat hem springen als je op een bepaalde toets drukt ...


    H4: Ster tekenen

     
    De verhoudingen vind je terug in de tekening (waarbij sin(30 graden)/2 = ±1/4  en  cos(30 graden)/2 = ±0.43)
    Tip: om een cardinal met de reele constante 0.43 te vermenigvuldigen, moet je deze naar een REAL omzetten. Dit kan je omzeilen door de cardinal te vermenigvuldigen als volgt: *43/100.
     Gebruik de graph-procedures Line  (zie onderaan).



    X1: Bitmaps

     Start with the code from  .
    We defined:




    T2: Output

    MODULE T2;
    <* NOOPTIMIZE + *>
    FROM IO IMPORT RdChar, WrChar, WrStr, RdStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdReal, WrReal, RdBool, WrBool;

        PROCEDURE Proc1(x, y, z: INTEGER): BOOLEAN;
        BEGIN
          x:= x + y + 1;
          RETURN x > z;
        END Proc1;

        PROCEDURE Proc2(arr: ARRAY OF INTEGER): INTEGER;

          VAR i: CARDINAL;
                    r: INTEGER;
        BEGIN
          FOR i := 0 TO HIGH(arr) DO
            r := arr[i];
          END;
          RETURN r;
        END Proc2;

        VAR a: INTEGER;            (* variable-declarations *)
            d:ARRAY[2..4] OF INTEGER;
    BEGIN
        WrLn;
        a := 1;
        d[2] := 3;
        d[3] := 4;
        d[4] := 4;
        WHILE Proc1(d[2], d[3], a) DO
          a := Proc2(d);
          DEC( d[3]);   (* definition of Decrement: DEC(n); is similar as n := n - 1; *)
          INC( d[4]);
        END;
        WrStr("a = ");WrInt(a, 0); WrLn;

    END T2.

    T3: Scope

    Schrijf tussen de haakjes (* .... *) alle identifiers (procedures, variabelen, types en constanten) die je op die lijn mag gebruiken.

    MODULE T3;
      FROM RealMath IMPORT pi;

      PROCEDURE X();
         CONST N=10;
         VAR b: CARDINAL;

         PROCEDURE Z();
           CONST pi=3.15;
           VAR c:CHAR;
         BEGIN
           (* ... *)
         END Z;

       BEGIN
         (* ... *)
      END X;
     
    VAR c:CHAR;
    BEGIN
      (* ... *)
    END T3.


    T4: Var & Val

    Wat is de output van het volgende programma?

    MODULE T4;
    <* NOOPTIMIZE + *>
    FROM IO IMPORT WrStr, WrChar, WrCard, RdCard, WrLn, WrInt;

      PROCEDURE Boe(VAR a: CARDINAL; b: INTEGER);
      BEGIN
        b := b + VAL(INTEGER, a);
        a := a + 2;

      END Boe;

    VAR
      x : CARDINAL;
      y : INTEGER;
    BEGIN
      x := 6;
      y:= 3;
      Boe(x, y);
      WrStr("x = ");WrCard(x, 0); WrLn;
      WrStr("y = ");WrInt(y, 0); WrLn;

    END T4.


    T4: Welke figuur?

    Welke figuur wordt er met deze code getekend? Vind het zonder het programma te runnen

    MODULE T3;
    <* WOFF + *> <* NOOPTIMIZE + *>
      FROM IO IMPORT WrStr, WrLn, RdCard, WrCard, RdInt, WrInt, RdKey, RdLn;
      FROM Lib IMPORT Delay; (* Delay: let the program wait a little time *)
          (* de graphics library vind je onder C:/Bin/Xds/Def/Ts/Graph.def *)
      FROM Graph IMPORT Init, Rectangle, Circle, Line, Disc, RawOutText;
      FROM Graph IMPORT _clrBLACK, _clrBLUE, _clrGREEN, _clrCYAN, _clrRED, _clrMAGENTA;
      FROM Graph IMPORT _clrBROWN, _clrWHITE, _clrGRAY, _clrLIGHTBLUE, _clrLIGHTGREEN;
      FROM Graph IMPORT _clrLIGHTCYAN, _clrLIGHTRED, _clrLIGHTMAGENTA, _clrLIGHTYELLOW, _clrBRIGHTWHITE;
                     (* deze 16 kleuren zijn constantes gaande van 0 tot 15 *)

    PROCEDURE Asterisk(x0,y0,size,colour:CARDINAL);
    (* Deze procedure tekent een ster met middelpunt x0, y0 en grootte size *)
       VAR a:CARDINAL;
     BEGIN
       a:= VAL(CARDINAL,((VAL(REAL,size)/(2.0))*0.7071) ); (* cos(45)*)
       Line(x0-size/2, y0, x0+size/2,y0, colour);
       Line(x0, y0+size/2, x0, y0-size/2, colour);
       Line(x0-a, y0+a, x0+a, y0-a, colour);
       Line(x0+a, y0+a, x0-a, y0-a, colour);
     END Asterisk;

    PROCEDURE Triangle(x0,y0,size,colour:CARDINAL);
    (* Deze procedure tekent een driehoek met middelpunt x0, y0 en grootte size *)
       VAR a:CARDINAL;
     BEGIN
       a:= VAL(CARDINAL,((VAL(REAL,size)/(2.0))*0.7071) ); (* cos(45)*)
       Line(x0, y0-a, x0-size/2, y0+a, colour);
       Line(x0-size/2, y0+a, x0+size/2, y0+a, colour);
       Line(x0, y0-a, x0+size/2, y0+a, colour);
     END Triangle;

    PROCEDURE RectangleExtra(x1, y1, breedte, hoogte, kleur:CARDINAL);
    (* Deze procedure tekent een rechthoek met linkerbovenhoek x1, y1 en gegeven breedte en hoogte
       Met nog extra 'dingen'  *)

    BEGIN
        Rectangle(x1, y1, x1+breedte, y1+hoogte, kleur, FALSE); (* rechthoek met gegeven linkerboven- en rechterbenedenhoek *)
        Triangle(x1, y1, breedte/4, kleur+1);
        Triangle(x1+breedte, y1+hoogte, breedte/4, kleur+2);
        Asterisk(x1  , y1+hoogte, breedte/4, kleur+3);
        Asterisk(x1+breedte, y1, breedte/4, kleur+4);
    END RectangleExtra;
       
      VAR
       x:CHAR;
    BEGIN

      (* Initialise graphics. Coordinatesystem: (0,0) is the top left corner *)
      IF NOT Init(1, 1 , 600, 600) THEN  (* creates a drawing window of 900 by 700 *)
        WrStr("Sorry, graphics doesn't work");WrLn;
        RETURN;
      END;
      (* Plot figures... *)

         Circle(300, 300, 100, _clrWHITE); (*circel met gegeven middelpunt en straal *)
         Asterisk(300, 300, 40, _clrGREEN);
         RectangleExtra (200, 200, 200, 200, _clrRED);

      (* Show graphics until user presses a key *)
      WrStr("Press any key to finish the program");
      x := RdKey();
      WrLn; RdLn;
    END T3.