Advertisement
madegoff

C_Kurs_5Blatt

Nov 8th, 2023
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.17 KB | None | 0 0
  1. /*
  2. Willkommen zum fünften Aufgabenblatt vom Programmierkurs. Auf diesem Aufabenblatt geht es um Rekursion.
  3.  
  4. Um die Tests für dieses Blatt zu kompilieren und zu starten, führen Sie den folgenden Befehl aus:
  5. cc -std=c11 -g -Wall 05ex_test.c -o 05ex_test.o -lm && ./05ex_test.o
  6. */
  7.  
  8. #include "05_canvas.h"
  9. #include <stdio.h>
  10. #include <math.h>
  11.  
  12. /*
  13. Aufgabe 1a:
  14. Zeichnen Sie eine horizontale Linie der Länge `width`, deren am weitesten links liegender Pixel bei `(x, y)` ist.
  15.  
  16. _Benutzen Sie keine Schleifen - Die Aufgabe soll über Rekursion gelöst werden!_
  17.  
  18. */
  19. Canvas recursive_line(Canvas c, int x, int y, int width) {
  20.  
  21.    //nicht rekursive Loesung:
  22.    /* while(width){
  23.  
  24.         if(x>=0&&y>=0&&x<canvas_width(c)&&y<canvas_height(c)){
  25.             canvas_set_black(c, x, y);
  26.         }
  27.         width--;
  28.         x++;
  29.     }
  30.  
  31.     return c;
  32.     */
  33.     if(width){
  34.  
  35.         if(x>=0&&y>=0&&x<canvas_width(c)&&y<canvas_height(c)){
  36.             canvas_set_black(c, x, y);
  37.         }
  38.         x++;
  39.         width--;
  40.         recursive_line(c,x,y,width);
  41.         }
  42.  
  43.     return c;
  44. }
  45.  
  46. /*
  47. Aufgabe 1b:
  48. Zeichnen Sie ein Rechteck mit der Breite `width` und der Höhe `height`. Der Pixel der linken unteren Ecke liegt bei `(x, y)`.
  49.  
  50. _Benutzen Sie keine Schleifen, die Aufgabe soll über Rekursion gelöst werden!_
  51. */
  52. Canvas recursive_rectangle(Canvas c, int x, int y, int width, int height) {
  53.  
  54.     /* nicht rekursive loesung:
  55.  
  56.     while(height){
  57.  
  58.         recursive_line(c,x,y,width);
  59.         y++;
  60.         height--;
  61.     }
  62.  
  63.     */
  64.  
  65.     if(height){
  66.         recursive_line(c,x,y,width);
  67.         y++;
  68.         height--;
  69.         recursive_rectangle(c,x,y,width,height);
  70.     }
  71.  
  72.     return c;
  73. }
  74.  
  75. /*
  76. Aufgabe 2:
  77. Der *Sierpinski Carpet der Ordnung 0* ist ein einzelnes schwarzes Pixel.
  78. Der *Sierpinski Carpet der Ordnung n+1* besteht aus acht Sierpinski Carpets der Ordnung n, angeordnet als drei-mal-drei
  79. Quadrat dessen Mittelstück fehlt.
  80.  
  81. Beispiele (`X` stellt schwarze Pixel dar)
  82. =========================================
  83.  
  84. Ordnung 0:
  85.  
  86. X
  87.  
  88. Ordnung 1:
  89.  
  90. XXX
  91. X X
  92. XXX
  93.  
  94. Ordnung 2:
  95.  
  96. XXXXXXXXX
  97. X XX XX X
  98. XXXXXXXXX
  99. XXX   XXX
  100. X X   X X
  101. XXX   XXX
  102. XXXXXXXXX
  103. X XX XX X
  104. XXXXXXXXX
  105.  
  106. Siehe auch die Datei `05sierpinski.jpg`
  107.  
  108. Aufgabe 2a:
  109. Um in der nächsten Aufgabe den Sierpinski-Carpet auf die Canvas zeichnen zu können müssen Potenzen berechnet werden.
  110. Implementieren Sie die Berechnung der Potenz einer nicht-negativen, ganzzahligen Basis `b` mit einem
  111. nicht-negativen, ganzzahligen Exponenten `exp`.
  112.  
  113. _Benutzen Sie keine Schleifen, die Aufgabe soll über Rekursion gelöst werden!_
  114. */
  115. int power(int b, int exp){
  116.  
  117.     int res;
  118.  
  119.     if (exp == 0) res = 1;
  120.     else if (exp == 1) res = b;
  121.  
  122.     else{
  123.     exp--;
  124.     res = power(b, exp)*b;
  125.     }
  126.  
  127.     return res;
  128. }
  129.  
  130. /*
  131. Aufgabe 2b:
  132. Diese Funktion soll den Sierpinski Carpet der Ordnung `n` auf die Canvas zeichnen, mit unterer linker Ecke an Koordinate `(x, y)`.
  133.  
  134. _Benutzen Sie keine Schleifen, die Aufgabe soll über Rekursion gelöst werden!_
  135. */
  136. Canvas sierpinski_carpet(Canvas c, int n, int x, int y){
  137.  
  138.     if(n==0){
  139.         canvas_set_black(c,x,y);
  140.     }
  141.     /*
  142.     else if(n==1){
  143.  
  144.         //linke 3 punkte des quaders
  145.         canvas_set_black(c,x,y); //f
  146.         canvas_set_black(c,x,y+1); //d
  147.         canvas_set_black(c,x,y+2); //a
  148.  
  149.         // oberer unt unterer punkt
  150.         canvas_set_black(c,x+1,y); //g
  151.         canvas_set_black(c,x+1,y+2); //b
  152.  
  153.         //rechte 3 punkte des quaders
  154.         canvas_set_black(c,x+2,y);    //j
  155.         canvas_set_black(c,x+2,y+1);   //e
  156.         canvas_set_black(c,x+2,y+2);   //c
  157.     }
  158.     */
  159.     else{ // muessen 8 "punkte"/einheiten faerben ;
  160.  
  161.         // abc
  162.         // d e
  163.         // fgj
  164.  
  165.         //fuer f startkoordinate = immer (x,y)
  166.         //fuer b = (x+1,y+2) bei n=1; b =(x+3, y+6) bei n=2 ; b = (x+9, y+18) bei n=3 -> (x+1*3^(n-1), y+2*3^(n-1))
  167.         //fuer g = (x+1,y) bei n=1; g = (x+3,y) bei n=2; g = (x+9, y) -> (x+1*3^(n-1), y)
  168.         //fuer d = (x, y+1) bei n=1; -> (x, y+1*3^(n-1))
  169.         //fuer a = (x, y+2) bei n=1; -> (x, y+2*3^(n-1))
  170.         // j = (x+2, y) -> (x+2*3^(n-1), y)
  171.         // e = (x+2, y+1) -> (x+2*3^(n-1), y+1*3^(n-1))
  172.         // c = (x+2, y+2) -> (x+2*3^(n-1), y+2*3^(n-1))
  173.  
  174.         int n_prev = n-1;
  175.  
  176.         int x_1 = x + 1*power(3, n_prev);
  177.         int x_2 = x + 2*power(3, n_prev);
  178.         int y_1 = y + 1*power(3, n_prev);
  179.         int y_2 = y + 2*power(3, n_prev);
  180.  
  181.  
  182.         sierpinski_carpet(c,n_prev,x,y); // bei (x,y) anfangen und 3x3 teppich zeichnen; aequvalent zu f
  183.         sierpinski_carpet(c,n_prev,x,y_1); // d
  184.         sierpinski_carpet(c,n_prev,x,y_2); // a
  185.  
  186.         sierpinski_carpet(c,n_prev,x_1,y); //g
  187.         sierpinski_carpet(c,n_prev,x_1,y_2); //b
  188.  
  189.         sierpinski_carpet(c,n_prev,x_2,y); //j
  190.         sierpinski_carpet(c,n_prev,x_2,y_1); //e
  191.         sierpinski_carpet(c,n_prev,x_2,y_2); //c
  192.     }
  193.     return c;
  194. }
  195.  
  196. /*
  197. Aufgabe 3:
  198. Implementieren Sie einen schwarzen Fülleimer. Gegeben eine Koordinate `(x, y)` auf einer (bereits bemalten) Canvas, soll die komplette
  199. zusammenhängende Fläche aller Pixel der selben Farbe (schwarz oder weiß) schwarz gefärbt werden.
  200. Zwei Pixel sind Teil der selben Fläche wenn sie die selbe Farbe haben und direkt benachbart sind. Jeder Pixel hat bis
  201. zu vier direkte Nachbarn - die Diagonalen zählen nicht.
  202.  
  203. Funktionen, um die Farbe eines Pixels auf der Canvas zu bestimmen, sind im Headerfile der Canvas dokumentiert.
  204. */
  205.  
  206. // Idee - betrachten ein Pixel und gehen in alle 4 richtungen (betrachten die Nachbarn), faerben die solange sie zur flaeche gehoeren
  207. // oder solange wir kein ende des canvas erreichen
  208. // das ganze wird rekursiv gemacht fuer jeden pixel der flaeche
  209.  
  210.  
  211. Canvas bucket_fill(Canvas c, int x, int y) {
  212.  
  213.     if(x<0 || x>canvas_width(c)-1 || y<0 || y>canvas_height(c)-1) return c; //passt nicht auf canvas
  214.     else {
  215.         if(pixel_is_black(c,x,y)==0){ //muessen faerben
  216.  
  217.             canvas_set_black(c,x,y); //faerben den punkt und betrachten seine nachbarn
  218.             bucket_fill(c,x+1,y);
  219.             bucket_fill(c,x-1,y);
  220.             bucket_fill(c,x,y+1);
  221.             bucket_fill(c,x,y-1);
  222.         }
  223.  
  224.     }
  225.  
  226.     return c;
  227. }
  228.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement