Soru: Üç noktanın koordinatlarını alarak bu noktalardan geçen eğriyi bezier algoritması ile ekrana çizen kodu yazınız.

Çözen : Şadi Evren ŞEKER

Çözüm:

Bezier eğrisini çizebilmek için ikinci dereceden bir denkleme ihtiyaç duyulur. Burada denklemin ikinci derece olmasının sebebi 3 nokta ile çizim yapılmasının istenmesidir.

Öncelikle programımızda kullanacağımız basit temel fonksiyonları kodlayalım:

İki nokta verildiğinde bu iki noktanın ortasındaki noktayı hesaplayan fonksiyonu kodlayalım:

(define (mid-point a-posn b-posn)

(make-posn

(mid (posn-x a-posn) (posn-x b-posn))

(mid (posn-y a-posn) (posn-y b-posn))))

Yukarıda iki sayının orta değerini (aritmetik ortalamasını) hesaplayan mid fonksiyonunu kullandık. Bu fonksiyonu basitçe iki sayının toplamının yarısı olarak aşağıdaki şekilde tanımlayabiliriz:

(define (mid x y)

(/ (+ x y) 2))

Artık bezier fonksiyonumuzu kodlayabiliriz. Buradaki püf noktası sürekli olarak noktaların arasındaki noktaların hesaplanmasıdır. Bu açıdan bir fraktal üretimine benzetilebilir:

(define ( bezier p1 p2 p3) (cond

[(too-small? p1 p2 p3) true]

[else (and (draw-solid-disk (mid-point (mid-point p1 p2) (mid-point p2 p3)) 3)

(bezier (mid-point (mid-point p1 p2) (mid-point p2 p3)) (mid-point p2 p3) p3)

(bezier p1 (mid-point p1 p2) (mid-point (mid-point p1 p2) (mid-point p2 p3)))

)]))

Yukarıdaki kod 3 nokta alıp bu noktalar arasındaki mesafe çizilemeyecek kadar küçük oluncaya kadar (bu mesafe aynı zamanda çizimdeki noktaların seyrekliğini de belirtmektedir) ara nokta hesaplamakta ve hesaplanan bu ara noktaları çizmektedir. Yukarıdaki fonksiyonda bitişi belirten too-small? Fonksiyonunu aşağıdaki şekilde tanımlayabiliriz:

(define (too-small? p1 p2 p3)(cond[(< (abs(- (posn-x p1) (posn-x p2))) 10) true]

[else false]

))

Burada noktalar arası mesafe 10 veya daha düşükse artık yeni nokta üretimi duracaktır.

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

(define p1 (make-posn 50 50))

(define p2 (make-posn 150 150))

(define p3 (make-posn 250 100))

Üç nokta tanımlanmıştır

(start 300 200)

Çizim alanı açılmıştır

(bezier p1 p2 p3)

Ve son olarak fonksiyonumuza üç nokta parametre verilmiştir.

Kodun çalıştıktan sonra ekranda oluşturduğu çizim aşağıdaki şekilde görülebilir

Yorumlar

  1. abdurrahman ulusoy

    Merhaba hocam
    sitenizdeki bezier eğrisi çizen kodu gambasa (linuxtaki visual basic denebilir) uyarladım. ama çıkan eğri bir bezier eğrisine benzemiyor.
    altta kodları gönderdim. hatayı da bulamadım. yardımcı olursanız sevinirim.
    Eğer kodları çözebilirsem. bezier eğrisini kedicad de spline çizimi olarak kullanacağım.

    Saygılarımla

    kodlar

    Public st As Float
    Public bgg As New Float[]
    Public sgs As New Float[]

    Public Sub dikdort2_Click()
    Dim f1x, f1y, f2x, f2y, t1x, t1y As Float
    st = 5000000
    bgg.Add(50) ' P1x 3 nokta için x y değerleri
    bgg.Add(50) ' P1y
    bgg.Add(175) ' P2x
    bgg.Add(250) ' P2y
    bgg.Add(350) ' P3x
    bgg.Add(400) ' P3y
    While st > 0.5 ' st> 0.5 olduğu müddetçe
    f1x = (bgg[0] + bgg[2]) / 2 'p1-p2 x ort
    f1y = (bgg[1] + bgg[3]) / 2 'p1-p2 y ort
    f2x = (bgg[2] + bgg[4]) / 2 'p2-p3 x ort
    f2x = (bgg[3] + bgg[5]) / 2 'p2-p3 y ort
    t1x = (f1x + f2x) / 2 '(p1-p2 ) (p2-p3 ) x ort
    t1y = (f1y + f2y) / 2 '(p1-p2 ) (p2-p3 ) y ort
    sgs.Add(t1x) ' ' asıl noktaları çizim için depola (draw - solid - disk(Mid - point(Mid - point p1 p2)(Mid - point p2 p3))3)
    sgs.Add(t1y) ' ' asıl noktaları çizim için depola (draw - solid - disk(Mid - point(Mid - point p1 p2)(Mid - point p2 p3))3)
    bezier(t1x, t1y, f2x, f2y, bgg[4], bgg[5], 0) ' beziere git ' (bezier(Mid - point(Mid - point p1 p2)(Mid - point p2 p3))(Mid - point p2 p3)p3)
    bezier(bgg[0], bgg[1], f1x, f1y, t1x, t1y, 1) ' beziere 2. kez git ' (bezier p1(Mid - point p1 p2)(Mid - point(Mid - point p1 p2)(Mid - point p2 p3)))
    Wend
    End

    Sub bezier(p1x As Float, p1y As Float, p2x As Float, p2y As Float, p3x As Float, p3y As Float, kn As Float)
    st = Hyp((p2x - p1x), (p2y - p1y)) ' uzunluk
    If kn = 0 ' beziere 2. kez gelindi
    bgg.Clear '3 nokta için x y değerlerini sil
    bgg.Add(p1x) ' yeni değerleri gir
    bgg.Add(p1y)
    bgg.Add(p2x)
    bgg.Add(p2y)
    bgg.Add(p3x)
    bgg.Add(p3y)
    End If
    Return
    End

Bir Cevap Yazın

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


× üç = 6