Soru: Bir poligonu ve bir sayıyı parametre olarak alan, verilen sayı kadar poligonu büyüterek iç içe çizen kodu yazınız.

Çözen : Şadi Evren ŞEKER

Çözüm fonksiyonları:

Öncelikle çizim yapacağımız için dr. Scheme üzerinde draw.ss teachpack’ini yüklememiz gerekiyor:

Ardından poligonu çizim için tanımlı noktalardan tanımlayalım:

(define a (make-posn 240 240))

(define b (make-posn 250 260))

(define c (make-posn 245 270))

(define d (make-posn 235 270))

(define ee (make-posn 230 260))

Buradaki son nokta ee isminde çünkü e ismi Dr. Scheme üzerinde doğal logaritma kökü olarak tanımlı.

Ardından poligonu büyütmek için poligondaki nokta koordinatlarını işleyecek olan temel fonksiyonlarımızı tanımlayalım:

(define (add-posn a b )( make-posn (+ (posn-x a ) (posn-x b)) (+ ( posn-y a )(posn-y b))))

(define (sub-posn a b )( make-posn (- (posn-x a ) (posn-x b)) (- ( posn-y a )(posn-y b))))

(define (mult-posn aposn ascalar)(make-posn (* ascalar (posn-x aposn)) (* ascalar (posn-y aposn))))

(define (round-posn aposn)(make-posn (round (posn-x aposn)) (round (posn-y aposn))))

Sırasıyla toplama, çıkarma, çarpma ve yuvarlama işlemi yapan fonksiyonlar, çizim için tanımlı nokta koordinatları üzerinde işlem yapıyor.

Yine çalışmamız sırasında gerekeceği için meşhur accumulate fonksiyonumuzu tanımlıyoruz:

(define accumulate

(lambda (f nv l)

(cond

((null? l) nv)

(else (f (car l) (accumulate f nv (cdr l)))))))

Ardından kodlamaya geçebiliriz. Sorunun çözümü olan kod aşağıda verilmiştir:

(define (gravity alist ) ( mult-posn (accumulate add-posn (make-posn 0 0) alist) (/ 1 (length alist))))

(define p (gravity (list a b c d)))

(define (draw-poly alist aposn color)( cond [(null? (rest alist)) (draw-solid-line (first alist) aposn color)][else (and (draw-solid-line (first alist) (first (rest alist)) color) (draw-poly (rest alist) aposn color))]))

(start 500 500)

(define polylist (list a b c d ee))

(define (new-posn a alist ascalar) (add-posn ( mult-posn ( sub-posn a (gravity alist)) ascalar) a))

(define (new-poly alist aliststatic ascalar) (cond[(null? alist) empty][else (cons (new-posn (first alist) aliststatic ascalar) (new-poly (rest alist) aliststatic ascalar)) ]))

(define (draw-num-poly num alist) (cond [(eq? num 0) empty][else (and ( draw-poly (new-poly alist alist (expt num 1.5)) (first (new-poly alist alist (expt num 1.5))) ‘blue) (draw-num-poly (- num 1) alist ))]))

Çözüm çalıştırması:

(draw-num-poly 5 polylist)

Açıklama:

Çözüm için draw-num-poly fonksiyonu kullanılmıştır. Bu fonksiyonda sayı ve polygonu içeren liste parametre alınmıştır. Poligonu içeren liste ise daha yukarıda polylist olarak ilk tanımlı noktalar üzerinden inşa edilmiştir.

Gravity fonksiyonumuz bir poligonu alıp, verilen boyut kadar (length) yeniden boyutlandırmaya yaramaktadır.

New-posn fonksiyonunda bir posn değeri alınarak bu gravity fonksiyonu uygulanmıştır.

New-poly fonksiyonunda ise bir poligonu içeren liste ve bir sayısal değer alınarak new-posn fonksiyonuna geçirilmiştir. Dolayısıyla bu fonksiyon poligondaki bütün elemanları dolaşır ve hepsinin yeniden boyutlandırılmasını sağlar.

Herşeyi başlatan fonksiyonumuz draw-num-poly ilse bir sayı ve bir listeyi değişken (variable) olarak almaktadır. Buradaki sayı 0 olana kadar fonksiyon özyineli (recursive) olarak listenin üzerinden geçer.

Bu sırada listedeki elemanları içeren poligonu çizer ve bir sonraki listeyi new-poly ile büyülterek hesaplatır. Hesaplanan bu yeni fonksiyon tekrar sayısal parametrenin bir eksiği ile fonksiyona verilir, ta ki sayı değeri 0 olana kadar.

Çalışmanın sonucunda görülen ekran yukarıda verilmiştir.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir