If you're seeing this message, it means we're having trouble loading external resources on our website.

Bağlandığınız bilgisayar bir web filtresi kullanıyorsa, *.kastatic.org ve *.kasandbox.org adreslerinin engellerini kaldırmayı unutmayın.

Ana içerik

Yerçekimsel çekim

Tüm kuvvetlerin en ünlüsü, muhtemelen, yer çekimi kuvvetidir. Biz insanlar yer çekimini, Isaac Newton'un kafasına düşen bir elma olarak düşünürüz. Yer çekiminin anlamı, her şeyin düştüğüdür. Ancak, bu sadece yer çekimi deneyimimizdir. Gerçekte, dünyanın yer çekimi kuvveti nedeniyle elmayı kendine çektiği gibi, elma da dünyayı çeker. Aslında, dünya çok büyük olduğu için, gezegenin üstündeki diğer nesnelerin hepsinin yer çekimi etkileşimlerini alt eder. Kütlesi olan her nesne, diğer nesnelerin hepsine yerçekimsel bir kuvvet uygular. Ve aşağıdaki şemada gösterilen bu kuvvetlerin güçlerini hesaplamak için bir formül vardır:
İki küre arasındaki yerçekimsel kuvvetlerin şeması
Bu formüle biraz daha yakından bakalım.
  • F yerçekimi kuvvetini, hesaplamak ve applyForce() fonksiyonumuza geçirmek istediğimiz vektörü ifade eder.
  • G, evrensel yer çekimi sabitidir, bu da bizim dünyamızda 6,67428 x 10-11 metreküp bölü kilogram bölü saniye kareye eşittir. İsminiz Isaac Newton veya Albert Einstein ise, bu çok önemli bir sayıdır. Bir ProcessingJS programcısıysanız, önemli bir sayı değildir. Yine, bu, dünyamızdaki kuvvetleri daha zayıf veya güçlü yapması için kullanabileceğimiz bir sabittir. Bunu bire eşitlemek ve göz ardı etmek de çok kötü bir seçenek değildir.
  • m, start subscript, 1, end subscript ve m, start subscript, 2, end subscript, 1 ve 2 nesnelerinin kütleleridir. Newton’un ikinci yasasında gördüğümüz gibi, (F, with, vector, on top, equals, M, A, with, vector, on top), kütle de yoksaymayı seçebileceğimiz bir şeydir. Ne de olsa, ekranda çizili şekillerin aslında fiziksel bir kütlesi yoktur. Ancak, biz bu değerleri tutarsak, “daha büyük” nesnelerin daha küçük olanlardan daha güçlü bir yerçekimsel kuvvet sarfettiği daha ilginç simülasyonlar yaratabiliriz.
  • r, with, hat, on top nesne 1'den nesne 2'ye uzanan birim vektörü gösterir. Birazdan göreceğimiz gibi, bu yön vektörünü hesaplamak için, bir nesnenin konumunu diğerinden çıkarabiliriz.
  • r, squared, iki nesnenin arasındaki uzaklığın karesini gösterir. Bunu biraz daha düşünelim. Hepsi formülün üstünde olduğu için, —G, m_1, m, start subscript, 2, end subscript—değer ne kadar fazla olursa, kuvvet o kadar fazla olur. Büyük kütle, büyük kuvvet. Büyük G, büyük kuvvet. Şimdi, bir şeye böldüğümüzde, bunun tam tersini elde ederiz. Kuvvetin gücü, uzaklığın karesiyle ters orantılıdır. Bir nesne ne kadar uzaktaysa, kuvvet o kadar zayıftır; ne kadar yakınsa, o kadar güçlüdür.
Umarız, artık formül biraz mantıklı gelmektedir. Bir şemaya baktık ve formülün bileşenlerini teker teker ayırdık. Artık matematiği ProcessingJS koduna çevirmenin zamanı geldi. Aşağıdaki varsayımları yapalım.
Elimizde iki nesne var, ve:
  1. Her nesnenin bir PVector konumu vardır: location1 ve location2.
  2. Her nesnenin sayısal bir kütlesi var: mass1 ve mass2.
  3. Evrensel yerçekimsel sabit, G için, bir sayısal değişken var.
Bu varsayımlara göre, bir PVector force, yerçekimi kuvvetini hesaplamak istiyoruz. Bunu iki bölümde yapacağız. Önce, yukarıdaki formüldeki kuvvetin yönünü, r, with, hat, on top , hesaplayacağız. İkinci olarak, kütleler ve uzaklığa göre, kuvvetin gücünü hesaplayacağız.
Bir nesnenin fareye doğru hızlanmasını nasıl sağladığımızı hatırladınız mı? Burada da aynı mantığı kullanacağız.
Bir vektör, iki nokta arasındaki farktır. Çemberden fareye uzanan bir vektör oluşturmak için, bir noktayı başka bir noktadan çıkardık:
var dir = PVector.sub(mouse, location);
Bizim durumumuzda, 1. nesnenin 2. nesneye uyguladığı çekim kuvveti şuna eşittir:
var dir = PVector.sub(location1, location2);
Bir birim vektör, sadece yönü belirten bir vektör, istediğimi için, konumları çıkardıktan sonra vektörü normalize etmemiz gerekir.
dir.normalize();
Tamam, kuvvetin yönünü bulduk. Şimdi buna göre, büyüklüğü hesaplamamız ve vektörü ölçeklememiz gerekir.
var m = (G * mass1 * mass2) / (distance * distance);
dir.mult(m);
Tek sorun, uzaklığı bilmiyor olmamızdır. G, mass1, ve mass2'nin hepsi verilmişti, ama üstteki kod çalışmadan önce, uzaklığı bulmamız gerekecek. Biz daha yeni bir konumdan ötekine uzanan bir vektör oluşturmadık mı? Bu vektörün uzunluğu, bu iki nesne arasındaki uzaklık olmaz mıydı?
Bir satır kod daha yazarsak ve bu vektörü normalize etmeden önce büyüklüğünü yakalarsak, uzaklığı elde etmiş oluruz.
// Bu nesneden ötekine uzanan vektör
var force = PVector.sub(location1, location2);

// Bu vektörün uzunluğu (büyüklük) iki nesne arasındaki uzaklıktır.
var distance = force.mag();

// Yer çekimi formülünü kullanarak kuvvetin gücünü hesaplayın.
var strength = (G * mass1 * mass2) / (distance * distance);

// Kuvvet vektörünü uygun büyüklükle normalize edin ve ölçekleyin.
force.normalize();
force.mult(strength);
Dikkat ederseniz, PVector “dir”i de “kuvvet” olarak yeniden isimlendirdim. Sonuçta, hesaplamaları bitirdiğimizde, baştaki PVector, gerçek kuvvet vektörümüz olur.
Artık (yerçekimini taklit eden) bir kuvveti hesaplamak için gereken matematiği ve kodu bulduğumuza göre, bu tekniği gerçek bir ProcessingJS programına uygulamaya bakmamız gerekir. Bu bölümde daha önce, basit bir Mover nesnesi oluşturmuştuk—PVector’ün konumu, hızı, ve ivmesinin yanı sıra applyForce() olan bir nesne. Bu sınıfı alalım ve bunu şununla bir programa koyalım:
  • Bir tek Mover nesnesi.
  • Tek Attractor nesnesi (sabit konumlu yeni bir tür nesne).
Mover nesnesi, şemada gösterildiği gibi, Attractor nesnesine doğru yerçekimsel bir çekim deneyimleyecektir.
Yeni Attractor nesnesini çok basit tutmakla başlayabiliriz—ona bir konum ve kütle veririz, ve kendini göstermesi için (kütleyi boyuta bağlayan) bir yöntem tanımlarız.
var Attractor = function() {
    this.position = new PVector(width/2, height/2);
    this.mass = 20;
    this.G = 1;
    this.dragOffset = new PVector(0, 0);
    this.dragging = false;
    this.rollover = false;
};

// Gösterilecek yöntem
Attractor.prototype.display = function() {
    ellipseMode(CENTER);
    strokeWeight(4);
    stroke(0);
    fill(175, 175, 175, 200);
    ellipse(this.position.x, this.position.y, this.mass*2, this.mass*2);
};
Bunu tanımladıktan sonra, Attractor nesne türünün bir örneğini oluşturabiliriz.
var mover = new Mover();
var attractor = new Attractor();

draw = function() {
    background(50, 50, 50);

    attractor.display();
    mover.update();
    mover.display();
};
Bu, iyi bir yapıdır: Mover ve Attractor nesneli bir ana program. Yapbozun son parçası, bir nesnenin diğerini çekmesini sağlamaktır. Bu iki nesnenin birbiriyle konuşmasını nasıl sağlayabiliriz?
Mimari olarak, bunu yapmanın birkaç yolu vardır. Burada birkaç olasılık görebilirsiniz.
Görevfonksiyon
1. Hem Attractor hem de Mover alan bir fonksiyon:attraction(a, m);
2. Attractor nesnesinde Mover nesnesi alan bir yöntem:a.attract(m);
3. Mover nesnesinde Attractor'ı alan bir yöntem:mover.attractedTo(a);
4. Attractor nesnesinde Mover'ı alan ve çekim kuvveti olan PVector'ü veren bir yöntem. Çekim kuvveti, sonra, Mover'ın applyForce() yöntemine geçirilir.`var f = a.calculateAttraction(m);
mover.applyForce(f);` |
Nesnelerin birbiriyle konuşmasını sağlamak için birkaç seçeneğe bakmak faydalıdır, ve üstteki olasılıkların her birini bir şekilde savunabilirsiniz. Birinciyi atmakla başlayalım, çünkü nesne-yönelimli bir yaklaşım, Mover veya Attractor nesnelerine bağlı olmayan rastgele bir fonksiyondan gerçekten çok daha iyi bir seçimdir. 2. veya 3. seçeneği seçmenin arasındaki fark, “Çekim noktası hareketliyi çeker” veya “Hareketli çekim noktasına çekilir.” demek arasındaki farktır. Bu derste bulunduğumuz yere göre, 4.'sü en uygun görünüyor. Ne de olsa, applyForce() yöntemini bulmak için çok zaman harcadık, ve aynı metodolojiyle devam edersek, örneklerimizin daha açık olacağını düşünüyorum.
Başka bir deyişle, şu varken:
var f = new PVector(0{,}1, 0); // Made up force
mover.applyForce(f);
Şimdi şunu elde ederiz:
var f = a.calculateAttraction(m); // Attraction force between two objects
mover.applyForce(f);
Ve şimdi draw() fonksiyonumuz şu şekilde yazılabilir:
draw = function() {
    background(50, 50, 50);

    // Calculate attraction force and apply it
    var f = a.calculateAttraction(m);
    mover.applyForce(f);

    attractor.display();
    mover.update();
    mover.display();
};
Neredeyse tamamladık. calculateAttraction() yöntemini Attractor nesne türünün içine koymaya karar verdiğimiz için, bu fonksiyonu gerçekten de yazmamız gerekir. Fonksiyonun bir Mover nesnesi alıp, PVector vermesi gerekir. Ve bu fonksiyona ne girer? Yerçekimi için bütün bu güzel matematiği çözdük!
Attractor.prototype.calculateAttraction = function(mover) {

    // Kuvvetin yönü nedir?
    var force = PVector.sub(this.position, mover.position);    
    var distance = force.mag();
    force.normalize();

    // Kuvvetin büyüklüğü nedir?
    var strength = (this.G * this.mass * mover.mass) / (distance * distance);
    force.mult(strength);

    // Uygulanabilmesi için, kuvveti verin!
    return force;
};
Ve bitti. Bir bakıma. Neredeyse. Düzeltmemiz gereken küçük bir tuhaflık kaldı. Üstteki koda yeniden bakalım. Bölme simgesini, eğik çizgiyi görüyor musunuz? Bunlardan biri elimizde olduğunda, kendimize şu soruyu sormamız gerekir: Uzaklık gerçekten çok küçük bir sayı (veya daha da kötüsü!) sıfır olduğunda, neler olur??! Evet, bir sayıyı 0'a bölemeyeceğimizi biliyoruz, ve bir sayıyı 0,0001 gibi bir şeye bölmek, 10.000 ile çarpmaya denktir! Evet,, bu yerçekiminin gücü için gerçek hayattaki formüldür, ama biz gerçek hayatta yaşamıyoruz. Biz ProcessingJS dünyası nda yaşıyoruz. ProcessingJS dünyasında, hareketli çekim noktasına çok çok yaklaşabilir, ve kuvvet o kadar kuvvetli olur ki, hareketli ekrandan dışarı uçar. Onun için, bu formülle, pratik olmamız ve bu uzaklığın olabileceği aralığı kısıtlamamız iyi olur. Belki, Mover nerede olursa olsun, çekim noktasından 5 pikselden az veya 25 pikselden fazla olduğunu düşünmemeliyiz.
distance = constrain(distance, 5, 25);
Aynı nedenle, minimum uzaklığı sınırlamamız gerekir, bunu maksimumla da yapmak fayda sağlar. Ne de olsa, hareketli çekim noktasından 500 piksel uzakta olsa (bu mantık dışı değildir) net kuvveti 250.000'e bölüyor oluruz. Bu kuvvet o kadar zayıf olabilir ki, hiç uygulamıyor gibi oluruz.
Artık, hangi davranışları istediğiniz size bağlıdır. Ama, “Garip miktarda zayıf veya kuvvetli olmayan mantıklı görünen bir çekim istiyorum” durumunda, uzaklığı sınırlamak iyi bir tekniktir.
Şimdi bunu bir programda birleştirelim. Mover nesne türü hiç değişmemiştir, ama şimdi programımız bir Attractor nesnesi, ve bunları birleştiren kod içerir. Çekim noktasını fareyle kontrol etmek için programa kod ekledik, böylece etkileri gözlemlemek daha kolay olur.
Sürtünmede yaptığımız gibi, bu örneği birçok Mover nesnesi için bir dizi kullanarak genişletebiliriz. Programımızda yaptığımız ana değişiklik, Mover nesnemizin (eskiden olduğu gibi) kütle, x, ve y almasını sağlamak, rastgele yerleştirilmiş bir Mover dizisini başlatmak, ve her seferinde, bunların çekim gücünü hesaplamak için bu dizide yineleme yapmaktır:
var movers = [];
var attractor = new Attractor();

for (var i = 0; i < 10; i++) {
    movers[i] = new Mover(random(0{,}1, 2), random(width), random(height));
}

draw = function() {
    background(50, 50, 50);

    attractor.display();
    for (var i = 0; i < movers.length; i++) {
        var force = attractor.calculateAttraction(movers[i]);
        movers[i].applyForce(force);

        movers[i].update();
        movers[i].display();
    }
};

Bu "Doğal Simülasyonlar" dersi, Daniel Shiffman'ın"Kodun Doğası"'nın bir türevidir ve Creative Commons Yüklemesi-Ticari Olmayan 3,0 Dağıtıma Açık Lisansla kullanılmaktadır.