Bu algoritmada, metaball denilen şey aslında bir enerji topudur. Yaydığı enerji, merkeze olan uzaklık arttıkça, azalır. Işık kaynağı gibi düşünebilirsiniz bir metaball'ı. Birbirine yaklaşan iki metaball'ın arasındaki enerji alanı, iki kaynaktan da etkilendiği için artar.
Bu algoritmada yapmanız gereken şey, önce istediğiniz sayıda ve güçte enerji kaynağı oluşturup, sonra ekrandaki her noktanın, her kaynak için enerji değerini hesaplayıp, o nokta üzerinde toplamak. Yani bu işlemin sonunda elinizde ekrandaki noktalar ve her birinin enerji değeri olacak.
Ondan sonra sıra render etmeye geliyor. Bu konuda tavsiyem, yazıya devam etmeden önce, kullandığınız dilin bir grafik kütüphanesini bulup, boş bir ekran açarak o ekranın pixellerinin rengini teker teker atamayı öğrenin. Bunu yapmazsanız, algoritmayı yazsanız da görsel bir sonuç elde edemezsiniz.
Kütüphanenizin fonksiyonlarını öğrendikten sonra, render kısmı da çok zor değil aslında, bir taban değer belirleyip, enerji değeri o değerden yüksek olan pixelleri renklendiriyorsunuz.
Algoritma kafanızda şekillenmiştir artık. Kodlamaya geçebiliriz.
Pseudocode:
genişlik = 320
yükseklik = 240
enerjiler = matris_oluştur(genişlik, yükseklik) //0 matrisi oluşturdum
// Kaynakları koordinatları ve enerjileriyle temsil ediyorum.
k1 = [(50, 50), 70]
k2 = [(200, 50), 70]
k3 = [(50, 130), 30]
k4 = [(250, 200), 40]
k5 = [(300, 100), 80]
kaynaklar = [k1, k2, k2, k3, k4, k5]
def hesapla(kaynaklar, enerjiler):
0 dan genişlik-1'e kadar her x için:
0 dan yükseklik-1'e kadar her y için:
kaynaklar'daki her kaynak için:
kx = kaynak[0][0]
ky = kaynak[0][1]
güç = kaynak[1]
dx = kx - x
dy = ky - y
uzaklık = kök(dx^2 + dy^2)
enerji = güç / (uzaklık + 0.00000000001) //0'a bölüm durumunda hata
enerjiler[x][y] = enerji //olacağı için çok çok küçük
//bir sayı ekliyorum.
resim = resim_oluştur(genişlik, yükseklik) //Beyaz bir resim oluşturdum.
resim.kapla(siyah) //Resmin tamamını siyaha boyadım.
taban_değeri = 3 //Seçtiğiniz kaynakların güçlerine orantılı bir taban değeri gerekiyor.
def boya(enerjiler, resim):
0 dan genişlik-1'e kadar her x için:
0 dan yükseklik-1'e kadar her y için:
eğer enerjiler[x][y] > taban_değeri ise:
resim.pixel_boya((x, y), renk)
Programı telefonumda yazıp sonucunu render ettim. Bu şekilde bir görüntü elde ediyoruz.
Düzleme, tek renk ile metaball'lar çizdik. Gözünüze çok sade görünebilir ama akışkan simulasyonları yapacaksanız oldukça kullanışlı bir algoritma. Örnek bir video göstereyim.
Şimdi gelelim bu algoritmanın farklı şekillerde kullanımına. Aklımda 2 farklı yol var size gösterebileceğim. Birincisi, taban değerinin üstündekileri boyamak yerine, tüm noktaları enerji değerine göre renklendirmek. Bunu yapmak için, enerji değerlerini belirli bir katsayıyla çarpıp, RGB renkteki renk değeri yerine yazıp, noktayı bu renkle boyamanız gerekiyor. Oldukça estetik bir görünüm veriyor parçacıklarınıza, bu yaklaşım.
Pseudocode:
def boya(enerjiler, resim):
0 dan genişlik-1'e kadar her x için:
0 dan yükseklik-1'e kadar her y için:
yeşil = int(255/3.0 * enerjiler[x][y][1])
resim.pixel_boya((x, y), (0, yeşil, 0))
Yukarıda yazdığımız kaynakların güçlerini biraz azaltarak render ettim. Çok fazla kaynak olduğundan çok parlak görünüyor resim. Kaynak sayısını azaltırsanız daha güzel görüntüler elde edersiniz. Benim bu şekilde yapmamın sebebi aradaki farkı göstermek istemem.
İkinci yol ise, farklı türden enerjiler, yani renkler. Bunu yapmak için, yukarıda güç dediğimiz özelliği de 3 elemandan oluşan bir liste yapmanız gerek. Bu 3 eleman rengin RGB değerleri olacak. Öncelikle farklı renkleri farklı türden enerjiler olarak düşünerek her nokta için 3 farklı enerji toplamı elde etmeniz gerek. Sonra da noktanın sahip olduğu farklı RGB enerjilerine göre bir renk çıkarıp o renge boyarsanız, bu algoritmayı farklı bir şekilde kullanmış olursunuz.
Pseudocode:
def boya(enerjiler, resim):
0 dan genişlik-1'e kadar her x için:
0 dan yükseklik-1'e kadar her y için:
kırmızı = int(255/3.0 * enerjiler[x][y][0])
yeşil = int(255/3.0 * enerjiler[x][y][1])
mavi = int(255/3.0 * enerjiler[x][y][2])
resim.pixel_boya((x, y), (kırmızı, yeşil, mavi))
Sadece bu örneklerle yetinmeyin. Rastgele sayıda ve rastgele güçlerde metaballlar oluşturmayı da deneyebilirsiniz. Gayet güzel sonuçlar alırsınız. Hatta bu şekilde elde ettiğiniz resimlerden wallpaper bile yapılabilir. Ayrıca asıl olarak, oyunlarınızda, animasyonlarınızda kullanabilirsiniz bu algoritmayı.
Bir yazının daha sonuna geldik. Umarım faydalı olabilmişimdir. Güzel bir gün geçirmeniz dileğiyle...






hocam pythonungucu.tk adlı sitenize giremiyorum site neden açılmıyor
YanıtlaSilO sitemi de bu blog gibi, gelen ilginin azlığı nedeniyle kapattım. Ülkede bu tarz şeylerle ilgilenen insan yok denecek kadar az. İngilizce çok rahat yazabilecekken Türkçe yazmakla halt etmişim onu sonradan fark ettim. Size ilginiz için özellikle teşekkür ediyorum, kusura bakmayın gerçekten.
YanıtlaSilhocam biraz daha sabırlı olabilirdiniz... Sizde benden fazlasını biliyorsunuz ki sitenin tanınması ve bulunması epey zaman alabilir.... ben bir haftadır uygun bir site arıyorum sitenizi başka bir sitede paylaşılmıştı.. oradan gördüm ama geçikmiş olmalıyım ki kapanmış... eğer imkanınız varsa sitenizi tekrar
Silaçabilir misiniz.. benim de bildiğim bir site felan var ben sizin sitenizi orada paylaşırım ve bu sayede birçok kişi engin bilgilerinizden istifade eder... size uygun değilse sitedeki dökümanları paylaşabilir misiniz bizde indirip öyle çalışalım... çok teşekkür ederim
İnsanlardan beklentimi biraz fazla tuttuğum için sanırım böyle oldu. Ama sayısı az da olsa, öğrenmeye istekli olan insanları mağdur etmek istemiyorum. Bana, blogun "Hakkımda" kısmından, mail aracılığıyla ulaşabilirsiniz. Sorularınızı yanıtlar, elimdeki kaynakları, dökümanları sizinle paylaşır, birebir ilgilenirim.
Silçok sağolun anlayışınız için .... çok teşekkürler
Silmerhaba hocam gayet güzel olmuş fakat biraz daha ayrıntılı anlatsanız . mesela görseller vermişsiniz ama kodları vermemişsiniz. birde bunları python da da yapabilirmiyiz.
YanıtlaSilTeşekkür ederim. Elimden geldiğince sade ve anlaşılır olmaya çalıştım. Konu anlatımı için kullandığım görseller dışında tüm görsellerin kodları yazıda mevcut. Ancak dilden bağımsız ve kolay anlaşılabilir olması için pseudocode ile yazdım. Tüm dillere uygulayabilirsiniz, buna python da dahil. Ben zaten python kullanarak programlayıp oluşturdum o resimleri.
Sil