Ana içerik
Konu: Bilgisayar Programlama > Ünite 5
Ders 5: Kuvvetler- Newton'un Hareket Yasaları
- Zor görev: Havada süzülen balon
- Çok sayıda nesnenin hareketi
- Bilgi Ölçme Yarışması: Duvar topları
- Yerçekimi ve sürtünmeyi modelleme
- Bilgi Ölçme Yarışması: Hız tümsekleri
- Hava ve sıvı direnci
- Bilgi Ölçme Yarışması: Batan kütükler
- Yerçekimsel çekim
- Zor görev: Sanat jeneratörü
- Karşılıklı çekim
- Bilgi Ölçme Yarışması: Karşılıklı itme
© 2024 Khan AcademyKullanım ŞartlarıGizlilik PolitikasıÇerez Politikası
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:
Bu formüle biraz daha yakından bakalım.
F
yerçekimi kuvvetini, hesaplamak veapplyForce()
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. ve ,1
ve2
nesnelerinin kütleleridir. Newton’un ikinci yasasında gördüğümüz gibi, ( ), 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. nesne1
'den nesne2
'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. , 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
, —değer ne kadar fazla olursa, kuvvet o kadar fazla olur. Büyük kütle, büyük kuvvet. BüyükG
, 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:
- Her nesnenin bir
PVector
konumu vardır:location1
velocation2
. - Her nesnenin sayısal bir kütlesi var:
mass1
vemass2
. - Evrensel yerçekimsel sabit,
G
için, bir sayısal değişken var.
Bu varsayımlara göre, bir , hesaplayacağız. İkinci olarak, kütleler ve uzaklığa göre, kuvvetin gücünü hesaplayacağız.
PVector force
, yerçekimi kuvvetini hesaplamak istiyoruz. Bunu iki bölümde yapacağız. Önce, yukarıdaki formüldeki kuvvetin yönünü, 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örev | fonksiyon |
---|---|
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.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.
Tartışmaya katılmak ister misiniz?
Henüz gönderi yok.