;; Gabi Roeger (load "program-1a.ss") (require-library "math.ss") ;; Aufgabe 2 ff. ; SIGNATUR ; pixel-color : picture circle -> color-bool ; ERKLAERUNG ; (pixel-color pic c) testet, ob der Kreis c das Bild pic schneidet. Falls nein -> #f. Falls ja, wird noch getestet, ob das Bild pic eingefaerbt ist. In diesem Fall gibt pixel-color den Farbwert zurueck, sonst #t. ; BEISPIELE ; Die Beipiele befinden sich bei den jeweiligen Einzelfunktionen. ; DEFINITION (define pixel-color (lambda (pic c) (cond ((ellipse? pic) (ellipse-hits pic c)) ((translate? pic) (translate-hits pic c)) ((scale? pic) (scale-hits pic c)) ((colored? pic) (color-hits pic c)) ((above? pic) (above-hits pic c)) ((polyline? pic) (polyline-hits pic c)) ((polygon? pic) (polygon-hits pic c)) ((rotate? pic) (rotate-hits pic c)) ((rotate-mat? pic) (rotate-mat-hits pic c)) (else #f) ))) ;; Aufgabe 3 ; SIGNATUR ; ellipse-hits : ellipse circle -> boolean ; ERKLAERUNG ; (ellipse-hits e c) gibt an, ob Ellipse e und Kreis c sich ueberschneiden. Falls ja -> true, sonst -> false ; BEISPIELE ; (ellipse-hits (make-ellipse #t 15 20) (make-circle (make-posn 9 5) 3)) == #t ; (ellipse-hits (make-ellipse #f 15 20) (make-circle (make-posn 13 3) 3)) == #t ; (ellipse-hits (make-ellipse #t 15 20) (make-circle (make-posn 30 5) 3)) == #f ; (ellipse-hits (make-ellipse #f 15 20) (make-circle (make-posn 9 5) 3)) == #f ; DEFINITION (define ellipse-hits (lambda (e c) (cond ((or (equal? 0 (ellipse-rx e)) (equal? 0 (ellipse-ry e))) #f) (else (cond ((ellipse-filled e) (<= (+ (/ (square (posn-x (circle-origin c))) (square (ellipse-rx e))) (/ (square (posn-y (circle-origin c))) (square (ellipse-ry e))) ) 1)) ((not (ellipse-filled e)) (cond ((or (<= (- (ellipse-rx e) (circle-radius c)) 0) (<= (- (ellipse-ry e) (circle-radius c)) 0)) (<= (+ (/ (square (posn-x (circle-origin c))) (square (+ (ellipse-rx e) (circle-radius c)) )) (/ (square (posn-y (circle-origin c))) (square (+ (ellipse-ry e) (circle-radius c)) ) )) 1)) (else (and (<= (+ (/ (square (posn-x (circle-origin c))) (square (+ (ellipse-rx e) (circle-radius c)) )) (/ (square (posn-y (circle-origin c))) (square (+ (ellipse-ry e) (circle-radius c)) ) )) 1) (cond ((or (<= (- (ellipse-rx e) (circle-radius c)) 0) (<= (- (ellipse-ry e) (circle-radius c)) 0)) #t) (else (> (+ (/ (square (posn-x (circle-origin c))) (square (- (ellipse-rx e) (circle-radius c))) ) (/ (square (posn-y (circle-origin c))) (square (- (ellipse-ry e) (circle-radius c))) ) ) 1) ))))))))))) ;; Aufgabe 4: ; SIGNATUR ; translate-hits : translate circle -> color-bool ; ERKLAERUNG ; (translate-hits t c) testet, ob Translate-Struktur t und Kreis c sich ueberschneiden. Falls nicht, gibt die Funktion #f zurueck. Falls ja, testet sie noch, ob die Struktur t eingefaerbt ist. In diesem Fall gibt sie den Farbwert zurueck, sonst true. ; BEISPIELE ; (translate-hits (make-translate (make-posn 20 10) (make-ellipse #t 30 20)) (make-circle (make-posn 40 30) 3)) == #f ; (translate-hits (make-translate (make-posn 20 10) (make-ellipse #t 30 20)) (make-circle (make-posn 40 15) 3)) == #t ; (translate-hits (make-translate (make-posn 20 10) (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20))) (make-circle (make-posn 40 30) 3)) == #f ; (translate-hits (make-translate (make-posn 20 10) (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20))) (make-circle (make-posn 40 15) 3)) == (make-rgb 1 1 0) == # ; DEFINITION (define translate-hits (lambda (t c) (pixel-color (translate-pic t) (make-circle (make-posn (- (posn-x (circle-origin c)) (posn-x (translate-delta t))) (- (posn-y (circle-origin c)) (posn-y (translate-delta t)))) (circle-radius c))))) ;; Aufgabe 5 ; SIGNATUR ; scale-hits : scale circle -> color-bool ; ERKLAERUNG ; (scale-hits s c) testet, ob Scale-Struktur s und Kreis c sich ueberschneiden. Falls nicht, gibt die Funktion #f zurueck. Falls ja, testet sie noch, ob die Struktur s eingefaerbt ist. In diesem Fall gibt sie den Farbwert zurueck, sonst true. ; BEISPIELE ; (scale-hits (make-scale (make-posn 2 1) (make-ellipse #t 30 20)) (make-circle (make-posn 40 30) 3)) == #f ; (scale-hits (make-scale (make-posn 4 1) (make-ellipse #t 30 20)) (make-circle (make-posn 40 15) 3)) == #t ; (scale-hits (make-scale (make-posn 4 1) (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20))) (make-circle (make-posn 40 15) 3)) == (make-rgb 1 1 0) == # ; DEFINITION (define scale-hits (lambda (s c) (cond ((or (equal? (posn-x (scale-scale s)) 0) (equal? (posn-y (scale-scale s)) 0)) #f) (else (pixel-color (scale-pic s) (make-circle (make-posn (/ (posn-x (circle-origin c)) (posn-x (scale-scale s))) (/ (posn-y (circle-origin c)) (posn-y (scale-scale s)))) (max (abs (/ (circle-radius c) (posn-x (scale-scale s)))) (abs (/ (circle-radius c) (posn-y (scale-scale s))))))))))) ;; Aufgabe 6 ; SIGNATUR ; color-hits : colored circle -> color-bool ; ERKLAERUNG ; (color-hits col c) testet, ob circle c die Colored-Struktur col schneidet. Wenn nein -> #f. Falls ja, testet sie noch, ob das Bild pic der colored-Struktur bereits eine Farbe hat. Wenn dies der Fall ist, uebergibt sie diese Farbe. Andernfalls uebergibt sie die Farbe color der colored-Struktur. ; BEISPIELE ; (color-hits (make-colored (make-rgb 0 1 1) (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20))) (make-circle (make-posn 40 15) 3)) == #f ; (color-hits (make-colored (make-rgb 0 1 1) (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20))) (make-circle (make-posn 10 5) 3)) == (make-rgb 1 1 0) == # ; (color-hits (make-colored (make-rgb 1 1 0) (make-ellipse #t 30 20)) (make-circle (make-posn 10 5) 3)) == (make-rgb 1 10) == # ; DEFINITION (define color-hits (lambda (col c) (cond ((pixel-color (colored-pic col) c) (cond ((rgb? (pixel-color (colored-pic col) c)) (pixel-color (colored-pic col) c)) (else (colored-color col)))) (else #f)))) ;; Aufgabe 7: ; SIGNATUR ; above-hits : above circle -> color-bool ; ERKLAERUNG ; (above-hits a c) testet, ob circle c die Above-Structur schneidet. Falls nicht, liefert sie #f zurueck. Falls ja, testet sie, ob der Kreis das upper-Bild der Above-Struktur schneidet. In diesem Fall gibt es dessen Farbe bzw. #t zurueck. Falls nicht, gibt sie die Farbe des lower-Bildes bzw. #t zurueck. ; BEISPIELE ; (above-hits (make-above (make-colored (make-rgb 0 1 0) (make-ellipse #t 30 40)) (make-ellipse #f 60 50)) (make-circle (make-posn 5 8) 2)) == (make-rgb 0 1 0) == # ; (above-hits (make-above (make-colored (make-rgb 0 1 0) (make-ellipse #t 30 40)) (make-ellipse #f 60 50)) (make-circle (make-posn 20 30) 2)) == #f ; (above-hits (make-above (make-colored (make-rgb 0 1 0) (make-ellipse #t 30 40)) (make-ellipse #f 60 50)) (make-circle (make-posn 3 49) 2)) == #t ; DEFINITION (define above-hits (lambda (a c) (cond ((pixel-color (above-upper a) c) (pixel-color (above-upper a) c)) (else (pixel-color (above-lower a) c))))) ;; Aufgabe 8: ; SIGNATUR ; polyline-hits : polyline circle -> boolean ; ERKLAERUNG ; (polyline-hits p c) liefert fuer eine polyline-Struktur p und einen Kreis c #t zurueck, falls sie sich schneiden. #f, sonst. ; BEISPIELE ; (polyline-hits (make-polyline (make-posn 3 6) (list (make-posn 30 27) (make-posn 20 13) (make-posn 10 40) (make-posn 40 3))) (make-circle (make-posn 25 22) 5)) == #t ; (polyline-hits (make-polyline (make-posn 3 6) (list (make-posn 30 27) (make-posn 20 13) (make-posn 10 40) (make-posn 40 3))) (make-circle (make-posn 22 10) 5)) == #f ; DEFINITION (define polyline-hits (lambda (p c) (cond ((null? (car (polyline-points p))) #f) ((polyline-hits-help (polyline-origin p) (car (polyline-points p)) c) #t) (else (cond ((null? (cdr (polyline-points p))) #f) ((polyline-hits-help (car (polyline-points p)) (cadr (polyline-points p)) c) #t) (else (polyline-hits (make-polyline (car (polyline-points p)) (cdr (polyline-points p))) c))))))) ;; Aufgabe 8: ; SIGNATUR ; polyline-hits-help: posn posn circle -> boolean ; ERKLAERUNG ; (polyline-hits-help pos1 pos2 c) testet, ob circle c die Strecke zwischen posn pos1 und posn pos2 schneidet. #t, falls ja. #f, falls nein. ; BEISPIELE ; (polyline-hits-help (make-posn 20 13) (make-posn 30 27) (make-circle (make-posn 25 22) 2)) == #t ; (polyline-hits-help (make-posn 20 13) (make-posn 30 27) (make-circle (make-posn 29 22) 2)) == #f ; DEFINITION (define polyline-hits-help (lambda (pos1 pos2 c) (cond ((equal? (posn-y pos1) (posn-y pos2)) (cond ((<= (abs (- (posn-y pos1) (posn-y (circle-origin c)))) (circle-radius c)) (cond ((or (and (<= (posn-x pos1) (+ (posn-x (circle-origin c)) (circle-radius c))) (>= (posn-x pos2) (- (posn-x (circle-origin c)) (circle-radius c)))) (and (<= (posn-x pos2) (+ (posn-x (circle-origin c)) (circle-radius c))) (>= (posn-x pos1) (- (posn-x (circle-origin c)) (circle-radius c))))) #t) (else #f))) (else #f))) (else (let* ((n (make-posn (- (posn-y pos2) (posn-y pos1)) (- (posn-x pos1) (posn-x pos2)))) (n0 (make-posn (* (posn-x n) (/ 1 (sqrt (+ (square (posn-x n)) (square (posn-y n)))))) (* (posn-y n) (/ 1 (sqrt (+ (square (posn-x n)) (square (posn-y n)))))))) (d (+ (* (posn-x n0) (- (posn-x (circle-origin c)) (posn-x pos1))) (* (posn-y n0) (- (posn-y (circle-origin c)) (posn-y pos1)))))) (cond ((> (abs d) (circle-radius c)) #f) ((<= (abs d) (circle-radius c)) (let* ((mue (/ (- (+ (posn-y (circle-origin c)) (/ (* (- (posn-x pos1) (posn-x (circle-origin c))) (posn-y n)) (posn-x n))) (posn-y pos1)) (- (- (posn-y pos2) (posn-y pos1)) (/ (* (posn-y n) (- (posn-x pos2) (posn-x pos1))) (posn-x n)))))) (cond ((and (>= mue 0) (<= mue 1)) #t) (else #f) ))))))))) ;; Aufgabe 9 ; SIGNATUR ; rotate-hits : rotate circle -> color-bool ; ERKLAERUNG ; (rotate-hits r c) testet, ob der Kreis c das rotate-Objekt r schneidet. Wenn ja, gibt sie entweder #t (falls das Objekt nicht eingefaerbt ist) oder einen Farbwert (falls das Objekt eingefaerbt ist) zurueck. Falls sich Keis und rotate-Objekt nicht schneiden: #f ; BEISPIELE ; (rotate-hits (make-rotate (/ pi 4) (make-ellipse #t 30 10)) (make-circle (make-posn 25 25) 2)) == #f ; (rotate-hits (make-rotate (/ pi 4) (make-ellipse #t 30 10)) (make-circle (make-posn -10 -9) 2)) == #t ; (rotate-hits (make-rotate (/ pi 4) (make-colored (make-rgb 1 0.8 0.3) (make-ellipse #t 30 10))) (make-circle (make-posn -10 -9) 2)) == (make-rgb 1 0.8 0.3) == # ; DEFINITION (define rotate-hits (lambda (r c) (let* ((phi (rotate-phi r)) (x (- (* (posn-x (circle-origin c)) (cos (- phi))) (* (posn-y (circle-origin c)) (sin (- phi))))) (y (+ (* (posn-x (circle-origin c)) (sin (- phi))) (* (posn-y (circle-origin c)) (cos (- phi)))))) (pixel-color (rotate-pic r) (make-circle (make-posn x y) (circle-radius c)))))) ;; Aufgabe 10: ; SIGNATUR ; polygon-hits : polygon circle -> boolean ; ERKLAERUNG ; (polygon-hits p c) testet, ob Polygon p und Kreis c sich ueberschneiden. Falls ja -> #t, sonst -> #f ; BEISPIELE ; (polygon-hits (make-polygon #t (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4))) (make-circle (make-posn 10 20) 2)) == #f ; (polygon-hits (make-polygon #t (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4))) (make-circle (make-posn 10 5) 2)) == #t ; (polygon-hits (make-polygon #f (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4))) (make-circle (make-posn 10 5) 1)) == #f ; (polygon-hits (make-polygon #f (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4))) (make-circle (make-posn 10 5) 2)) == #t ; DEFINITION (define polygon-hits (lambda (p c) (let ((l (append (polygon-points p) (list (polygon-origin p))))) (cond ((polygon-filled p) (cond ((polyline-hits (make-polyline (polygon-origin p) l) c) #t) (else (polygon-filled-hits (make-polygon #t (polygon-origin p) l) c (polygon-origin p))))) (else (polyline-hits (make-polyline (polygon-origin p) l) c)))))) ;; Aufgabe 10: ; SIGNATUR ; polygon-filled-hits : polygon circle posn -> boolean ; ERKLAERUNG ; (polygon-filled-hits p c o) gibt an, ob der Kreimittelpunkt von c im Polygon p liegt. o ist Hilfsvariable, in der (wegen der Rekursion) der Ursprung des von polygon-filled uebergebenen Polygons steht. ; BEISPIELE ; (polygon-filled-hits (make-polygon #t (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4))) (make-circle (make-posn 10 20) 2) (make-posn -20 3)) == #f ; (polygon-filled-hits (make-polygon #t (make-posn -20 3) (list (make-posn -9 36) (make-posn 13 3) (make-posn 10 -20) (make-posn -16 -4) (make-posn -20 3))) (make-circle (make-posn 10 5) 2) (make-posn -20 3)) == #t ; DEFINITION (define polygon-filled-hits (lambda (p c o) (cond ((equal? o (cadr (polygon-points p))) (cond ((equal? (polygon-help (polygon-origin p) (car (polygon-points p )) c) (polygon-help (car (polygon-points p)) (cadr (polygon-points p)) c)) #t) (else #f))) ((equal? (polygon-help (polygon-origin p) (car (polygon-points p)) c) (polygon-help (car (polygon-points p)) (cadr (polygon-points p)) c)) (polygon-filled-hits (make-polygon #t (car (polygon-points p)) (cdr (polygon-points p))) c o)) (else #f)))) ;; Aufgabe 10: ; SIGNATUR ; polygon-help : posn posn circle -> boolean ; ERKLAERUNG ; (polygon-help p q c) testet, auf welcher Seite der gerichteten Geraden, die durch die Strecke p -> q gegeben ist, der Kreismittelpunkt von c liegt. Sie gibt #f fuer rechts, und #t fuer links zurueck ; BEISPIELE ; (polygon-help (make-posn -8 -9) (make-posn -8 7) (make-circle (make-posn 6 7) 1)) == #f ; (polygon-help (make-posn -10 9) (make-posn 8 9) (make-circle (make-posn 6 15) 1)) == #t ; (polygon-help (make-posn -10 15) (make-posn 8 -24) (make-circle (make-posn 6 20) 1)) == #t ; DEFINITION (define polygon-help (lambda (p q c) (let ((n (- (* (- (posn-x p) (posn-x (circle-origin c))) (- (posn-y q) (posn-y (circle-origin c)))) (* (- (posn-x q) (posn-x (circle-origin c))) (- (posn-y p) (posn-y (circle-origin c))))))) (cond ((< n 0) #f) ((> n 0) #t))))) ;; Aufgabe 11: ; Structur rotate-mat (define-struct rotate-mat (a1 a2 pic)) ; a1 : number ; a2 : number ; pic : picture ; (make-rotate-mat a1 a2 pic) repraesentiert das Bild pic, nachdem es mit der Rotationsmatrix gedreht wurde. Die 2x2-Rotationsmatrix wird durch a1 und a2 folgendermaßen dargestellt: (Element links-oben ist Element rechts-unten: a1) (Element rechts-oben: (- a2)) (Element links-unten: a2) ;; Aufgabe 11: ; SIGNATUR ; rotate-mat-hits : rotate-mat circle -> color-bool ; ERKLAERUNG ; (rotate-mat-hits r c) testet, ob der Kreis c das rotate-mat-Objekt r schneidet. Wenn ja, gibt sie entweder #t (falls das Objekt nicht eingefaerbt ist) oder einen Farbwert (falls das Objekt eingefaerbt ist) zurueck. Falls sich Keis und rotate-mat-Objekt nicht schneiden: #f ; BEISPIELE ; (rotate-mat-hits (make-rotate-mat (cos (/ pi 4)) (sin (/ pi 4)) (make-ellipse #t 30 10)) (make-circle (make-posn 10 2) 2)) == #t ; (rotate-mat-hits (make-rotate-mat (cos (/ pi 4)) (sin (/ pi 4)) (make-colored (make-rgb 0 1 0) (make-ellipse #t 30 10))) (make-circle (make-posn 10 2) 2)) == (make-rgb 0 1 0) ; (rotate-mat-hits (make-rotate-mat (cos (/ pi 4)) (sin (/ pi 4)) (make-ellipse #t 30 10)) (make-circle (make-posn 15 0) 2)) == #f ; DEFINITION (define rotate-mat-hits (lambda (r c) (let* ((x (+ (* (rotate-mat-a1 r) (posn-x (circle-origin c))) (* (rotate-mat-a2 r) (posn-y (circle-origin c))))) (y (+ (* (- (rotate-mat-a2 r)) (posn-x (circle-origin c))) (* (rotate-mat-a1 r) (posn-y (circle-origin c)))))) (pixel-color (rotate-mat-pic r) (make-circle (make-posn x y) (circle-radius c)))))) ; Aufgabe 11: ; SIGNATUR ; picture-optimize : picture -> picture ; ERKLAERUNG ; (picture-optimize pic) ersetzt alle rotate-Strukturen in Bild pic durch rotate-mat-Strukturen. ; BEISPIELE ; (picture-optimize (make-rotate (/ pi 4) (make-ellipse #t 30 10))) == ; (make-rotate-mat (cos (/ pi 4)) (sin (/ pi 4)) (make-ellipse #t 30 10)) ; (picture-optimize (make-scale (make-posn 2 1) (make-rotate (/ pi 4) (make-ellipse #t 30 10)))) == ; (make-scale (make-posn 2 1) (make-rotate-mat (cos (/ pi 4)) (sin (/ pi 4)) (make-ellipse #t 30 10))) ; (picture-optimize (make-ellipse #f 15 40)) == (make-ellipse #f 15 40) ; DEFINITION (define picture-optimize (lambda (pic) (cond ((rotate? pic) (let ((a1 (cos (rotate-phi pic))) (a2 (sin (rotate-phi pic)))) (make-rotate-mat a1 a2 (picture-optimize (rotate-pic pic))))) ((ellipse? pic) pic) ((polyline? pic) pic) ((polygon? pic) pic) ((colored? pic) (make-colored (colored-color pic) (picture-optimize (colored-pic pic)))) ((translate? pic) (make-translate (translate-delta pic) (picture-optimize (translate-pic pic)))) ((scale? pic) (make-scale (scale-scale pic) (picture-optimize (scale-pic pic)))) ((above? pic) (make-above (picture-optimize (above-lower pic)) (picture-optimize (above-upper pic)))) ((translate-mat? pic) (make-translate-mat (translate-mat-a1 pic) (translate-mat-a2 pic) (picture-optimize (translate-mat-pic pic)))))))