15 Temmuz 2012 Pazar

Python kütle çekim simülasyonu - Bölüm 2

Yazımızın ilk kısmında arayüz ve cisimle ilgili sınıfları tanımlamıştık. Şimdi iki cisim arasındaki kütle çekim kuvvetini hesaplayacak fonksiyonu yazmaya başlayabiliriz. Bu esnada ikisi arasındaki mesafeyi hesaplamaya ihtiyacımız olacak. Her ikisinin de x ve y kordinatlarını bildiğimizden pisagor teoremini kullanarak bunu hesaplayabiliriz:

 
 def distance(ball1, ball2):
    return math.sqrt((ball1.x-ball2.x)**2+(ball1.y-ball2.y)**2) 
--To be continued--

Python kütle çekim simülasyonu - Bölüm 1

Merhabalar. Bu yazımızda her evde bulabileceğiniz malzemelerle (python, tkinter ve canvas) ufak bir simülasyon yazacağız.

Simülasyon belirli sayıda dairesel cisim oluşturmamıza izin verecek ve bunların iki boyutlu uzaydaki harekatlerini inceleyecek.

Programlamaya başlamadan önce newton mekaniğini biraz hatırlayalım. Birbirinin kütle çekimi etkisindeki iki cisim arasındaki çekim kuvveti eşittir ve şu formülle hesaplanır:



Daha ayrıntılı incelemek isterseniz ilgili vikipedi makalesi gayet bilgilendirici. Simülasyonumuzda sadece görüntü ile ilgileneceğiz dolayısıyla birimler arasındaki tutarlılığı sağlayan G sabiti bizi pek de ilgilendirmiyor şimdilik.

Bu kuvvetin cisimler üzerindeki etkisni hesaplamak için de


  formülünü kullanacağız. Simülasyonu basit tutmak ve birim adımdaki işlem yükünü azaltmak için her adımdaki ivmenin sabit olduğunu varsayacağız.

Cismimizin kütlesini simülasyonu oluştururken gireceğimizden ve kuvveti her adımda hesaplayacağımızdan ivmeyi de bulmak zor olmayacak. İvme ve cismin önceki hızını kullanarak da konumu x = x0 + v*dt+a*dt^2/2 formülüyle hesaplayacağız.

Şimdiye kadar incelediğimiz üzere, bu hesaplamalar esnasında cismin kütlesini, konumunu (ekranda göstermek ve mesafeyi hesaplamak için) ve hızını hafızada saklamamız gerecek. İvme ve kuvveti ise anlık olarak hesaplayabileceğiz.

Öyleyse artık programlamaya başlayabiliriz. İlk olarak cisim için bir sınıf oluşturalım. Tüm cisimleri dairesel şekillerle göstereceğimizden Ball adını sınıf için uygun gördüm:

 
 
class Ball:
    def __init__(self, x,y,speed_x=0,speed_y=0,m=1):
        self.x = x
        self.y = y
        self.speed_x = speed_x
        self.speed_y = speed_y
        self.force_x = 0
        self.force_y = 0
        self.m = m  

Az önce bahsettiklerimiz haricinde force_x ve force_y adlı iki değişken daha tanımladık. Bunları bir bütün cisimlerin kütle çekimlerini toplayıp tek bir kuvvetmiş gibi hesaplamak için kullanacağız.Cisimlerin görüntülenmesi için de Tkinter kütüphanesinin Canvas sınıfından bir simülasyon sınıfı türeteceğiz.
 
class Simulation(Canvas):
    def __init__(self):
        Canvas.__init__(self, width=1000, height=700)
        self.balls = []
        self.circles = [] 

Burada balls dizisi cisimlerimizi, circles dizisi ise bunların çizimlerini saklayacak.

Her şeyi bir araya getirirsek:

 
from Tkinter import *
import math
import time

# siniflari buraya yapistirin

mainWindow = Tk()
sim = Simulation()
sim.pack()

while True:
    mainWindow.update()
    sim.update()
 

Programı bu haliyle çalıştırdığınızda sim sınıfının update adlı bir methodu olmadığına dair bir hata raporu alırsınız. Simulation sınıfının görüntüyü güncellemesini sağlayacak methodu yazmadan önce cisimleri ekleyebilmemizi sağlayacak olan methodu yazalım:

 
    def addBall(self, x,y,speed_x=0,speed_y=0,m=1):
        self.balls.append(Ball(x,y,speed_x,speed_y,m))
 
Hemen bu şekilde bir cisim tanımlayalım:
 
sim.addBall(100,100)

while True:
    mainWindow.update()
    sim.update()
 
Artık bir cismimiz de olduğuna göre update() methodunu yazmaya başlayabiliriz:
 
    def update()
        for i in self.circles:
            self.delete(i)
        for i in range(len(self.balls)):    
            ball = self.balls[i]
            self.circles.append(self.create_oval(ball.x-5, ball.y-5, ball.x+5, ball.y+5, width=2, fill='blue'))
 
Burada her daireyi tek tek silmek yerine self.delete("all") methodunu kullanabilirdik ancak ileride cisimlerin izlediği yolları da çizdirebilmek için tek tek silmek daha mantıklı olacaktır.

Şimdiye kadar simülasyonumuz çalışacağı alt yapıyı kurduk. Yazımızın ikinci kısmında kütle çekimi hesaplamaya ve cisimleri hareket ettirmeye başlayacağız.

12 Temmuz 2012 Perşembe

Hello, World!

12.07.12 - 20:29 Yalova