
Fonksiyon çizici iş başında
Nedir?
Scientific Computing ile uğraşanların en çok karşılaştıkları karın ağrısı “Visualization” olsa gerek. Fonksiyon çizdirme ise, visualization denen kulenin ilk basamağıdır. Dört boyutlu nesne çizimlerine kadar gidilebiliyor. (Hypercube çizimi yakında NPK’ da!)
Bu örneğimizde, verilen bir fonksiyonu x eksenindeki noktaları sabit kalmak üzere “kabaca” çizdireceğiz. Burada VB6 ortamı kullanılıyor olması sizi endişelendirmesin, zira önemli olan kullanılan tekniktir, dil değil!
Aşamalar
Elimizdeki fonksiyonu çizmek için öncelikle bir ayrıklaştırma (discriminization) yapmamız gerekiyor. Neden? Çünkü efendim bilgisayar bu analog sinyali (Verdiğimiz fonksiyon esasında analog bir sinyale tekabül eder, sonsuz adet noktadan oluşur) tek kelime ile anlamaz! Bilgisayar ortamında tabi ki her şey ayrıktır. Yukarıda görmüş olduğunuz grafik sonlu sayıda noktacıktan oluşur. Yani ilk aşama, ayrıklaştırma!
1.Ayrıklaştırma
Esasında bize gerekli olan, x ve y koordinatları belli olan yeterli sayıda nokta. Bu noktaları çizgi (bildiğiniz düz çizgi) ile birleştirince, yukarıdaki grafiği elde edeceğiz. Tuvalimizi (canvas deyince çok da güzel oluyor lakin neden tuval saçma oluyor?) x ekseni yönünde 100 parçaya böldüğümüzü düşünelim. Bu sayede, her noktanın x koordinatlarını kafadan biliyor olacağız. Tek yapmamız gerekecek olan şey, y koordinatını düşünmek olacak.
O halde global bir X dizesi tanımlıyor ve içini dolduruyorum.
For i = 1 To 100
X(i) = f(i / zoom)
Next
Burada gördüğünüz zoom değişkeni de, çözünürlüğü artırmak amacıyla eklenmiş bir “teferruat”. Bunu yazının ileriki aşamalarında anlattım, merak etmeyiniz.
X dizesi elimizde olduğuna göre, bu x değerlerine karşılık gelen y değerlerini bulmamız gerekiyor. Bunu için de efendim yine evaluation dediğimiz sürece ihtiyaç duyuluyor.
2. Evalüasyon
Çizdirmemiz gereken fonksiyon bize çok değişik yollardan verilmiş olabilir. Her durum için bu fonksiyonun değerini hesaplayacak bir rutin yazamayız. Çözüm: parser!
Bize, metin olarak verilmiş bir matematiksel ifadeyi alıp, analiz edip ayrıştırıp sonucu da en azından double cinsinden döndürecek bir yol gerek. İnternette çok çeşitli bu tarz “math parser” bulmak mümkün. Ben, VB6 ile birlikte gelen Microsoft Script Control’ü kullandım. Bu kontrol, esasında metin olarak verdiğiniz vb script kodlarını çalıştırıyor. Bunun yanında, “eval” isimli bir metodu var ki yukarıda bahsettiğimiz işi yapıyor.
Bu durumda, herhangi bir f(x) değerini hesaplayacak fonksiyon şudur:
Function f(fonksiyon, X) As Double
On Error Resume Next
Dim ifd As String
ifd = Replace(fonksiyon, “x”, Replace(X, “,”, “.”))
f = Me.ScriptControl1.Eval(ifd)
End Function
Fonksiyon adlı değişken, bizim değerini bulmak istediğimiz fonksiyonun metin hali. Yani şöyle bişey canım;
fonksiyon = “x^2 + 2*x”
bunu alıyoruz, x yazan yere, f(x)’ini bulmak istediğimiz x değerini koyuyor ve bu ifadeyi hesaplattırıyoruz. Örneğin yukarıdaki fonksiyonun 3 noktasındaki değerini bulmak için, fonksiyon metninde x gördüğümüz yere 3 yazıp, sonucu hesaplıyoruz.
F(2) = 3^2 + 2*3
3.Çizim
Şimdi bize gerekli olan nokta kümesini oluşturabilir ve fonksiyonu çizdirebiliriz.
Private Sub Çiz()
On Error Resume Next
pct.Cls
pct.ScaleLeft = -2
pct.ScaleWidth = 104
pct.ScaleTop = fMax + (fMax * 0.09)
pct.ScaleHeight = (fMin – fMax) – 2 * (fMax * 0.09)
For i = 1 To 99
pct.Line (i, X(i))-(i + 1, X(i + 1)), renk
If X(i) = fMin Or X(i) = fMax Then
pct.Circle (i, X(i)), 1, vbRed
End If
Next
‘fonksiyonu yazdır
pct.CurrentX = 0.7
pct.CurrentY = fMax + fMax * 0.08
pct.ForeColor = vbBlack
pct.FontBold = True
pct.Print fonksiyon
Call EksenÇiz
End Sub
Burada esas baş ağrıtan kısım, picturebox nesnesini scale etmek. Bu işlemi her fonksiyonun görünen maksimum ve minimum değerleri farklı olduğu için, tekrar tekrar yapmak durumundayız.
Buradaki fMax ve fMin fonksiyonları sayesinde, fonksiyonun bizim tanımladığımız aralığındaki maksimum ve minimum değerlerini buluyoruz. Şöyle;
Function fMin()
mn = X(1)
For i = 1 To 100
If X(i) < mn Then mn = X(i)
Next
fMin = mn
End Function
Function fMax()
mx = X(0)
For i = 1 To 100
If X(i) > mx Then mx = X(i)
Next
fMax = mx
End Function
Scale Hedesi
pct.ScaleLeft = -2
Satırı ile, picturebox üzerindeki orijin (başlangıç) noktamızı, biraz sağa kaydırıyoruz. Yani diyoruz ki, -2 olsaydı tam en sola denk gelecekti, demek ki sıfırı biraz daha sağa gelicek!
pct.ScaleWidth = 104
biz tuvali 100 parçaya bölmüş idik. Demek ki grafiğin uzunluğu 100 birim olacak. Sol ve sağdan biraz ofset bırakmak için genişliği 104 birim yaptık.
pct.ScaleTop = fMax + (fMax * 0.09)
fonksiyonumuz en yüksek değerinde iken, picturebox’un en üst noktasına değecektir (mantıken). Biz yine üst kısımda biraz boşluk bırakmak amacıyla fonksiyonun maksimum değerine, %9’u kadarını daha ekliyoruz. Şimdi birileri çıkıp ta, neden elle bir değer vermedin, fMax + 1.5 yapmadın da gidip yine fMax’a bağlı bir değer ekledin diyebilir. fMax her fonksiyon için acayip derecede (dramatik) değişebilmekte ve bizim elle vereceğimiz değerin hiçbir hükmü olmayabilmekte olacaktır (ha?)
pct.ScaleHeight = (fMin – fMax) – 2 * (fMax * 0.09)
Esasen, scale işinin en büyük numarası bu scaleHeight işini halletmekte. Bu değeri negatif verirseniz, orijin aşağıdan başlayacaktır (bizim istediğimiz gibi). Eğer pozitif bir değer verirseniz, orijin sol üst köşe olur ki, grafik çizdirirken sürekli y değerlerini picturebox’ın scaleHeight değerinden çıkarmanız gerekir. Burada biz bir de yine üstten ve alttan %9 oranında boşluk bırakmak için ekleme yapmışız. (eksi olduğuna bakmayın, o bir ekleme).
Son Lakırdı
“Kabaca” lafının içini en güzel şekilde dolduracak bir biçimde fonksiyon çizimi yaptık. Umarım biraz da olsa “fikir” vermiştir zira kimseye “akıl” verecek haddime değildir. Köşenin doğası gereği bilimsel olmaktan uzak, daha çok sonuca yönelik, keyfe keder, neşesine bir projeydi efendim, diğer bir PNK’ da görüşmek üzere neş’e içerisinde kalınız.
Proje dosyalarını indir
YandanBaksanalan 3:09 pm on Eylül 1, 2010 Kalıcı Bağlantı |
Yazılarını severek okuyorum, başarılarını diliyorum. Emeğe saygı.