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

Kuvvet içeren parçacık sistemleri

Şimdilik bu bölümde, bir parçacık grubunu yönetmek için, kodumuzu nesne yönelimli bir şekilde yapılandırmaya odaklanıyorduk. Belki farkına vardınız, veya varmadınız; ama bu süreç boyunca, daha önceki bölümlerdeki yerimizden geri adım attık. Basit Parçacık nesnemizin yapısını inceleyelim:
var Particle = function(position) {
  this.acceleration = new PVector(0, 0{,}05);
  this.velocity = new PVector(random(-1, 1), random(-1, 0));
  this.position = new PVector(position.x, position.y);
  this.timeToLive = 255{,}0;
};
Ve şimdi update() yöntemine bakalım:
Particle.prototype.update = function(){
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.timeToLive -= 2;
};
Dikkat ederseniz, ivmemiz sabittir, yapıcının dışında oluşturulmamıştır. Çok daha iyi bir yöntem Newton'ın ikinci yasasını (F, with, vector, on top, equals, M, A, with, vector, on top) izlemek ve bunu Kuvvetler bölümünde üzerinde çok çalıştığımız kuvvet biriktirme algoritması ile birleştirmek olacaktır.
Birinci adım, bir applyForce() yöntemi eklemektir. (Unutmayın, kütleye bölmeden önce, PVector'un bir kopyasını yapmamız gerekir.)
Particle.prototype.applyForce = function(force) {
  var f = force.get();
  f.div(this.mass);
  this.acceleration.add(f);
};
Bunu bulduktan sonra, update()'in sonunda ivmeyi silmek için bir kod satırı daha ekleyebiliriz.
Particle.prototype.update = function() {
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.acceleration.mult(0);
  this.timeToLive -= 2{,}0;
};
Böylece, kuvvet uygulanabilir bir Particle nesnemiz olur. Şimdi, applyForce() fonksiyonunu nerede çağırmalıyız? Kodun neresinde parçacığa kuvveti uygulamak uygun olur? İşin aslını isterseniz doğru veya yanlış cevap yoktur; bu tamamen belirli bir programın fonksiyonlarına ve hedeflerine bağlıdır. Bununla birlikte, çoğu duruma uygun olacak genel bir durum yaratabiliriz ve bir sistemdeki bireysel parçacıklara kuvvetler uygulamak için bir model geliştirebiliriz.

Rüzgarı ekleme

Aşağıdaki hedefi düşünün: Tüm parçacıklara her seferinde draw() yoluyla genel bir kuvvet uygulama. Parçacıkları sağa iten, basit bir rüzgar şeklinde kuvvet uygulamayla başlayalım:
var wind = new PVector(0,4, 0);
Her zaman uygulanması gerektiğini söylemiştik, draw()'a olduğu gibi, onun için şimdiki haliyle draw() fonksiyonuna bakalım.
draw = function() {
  background(168, 255, 156);
  particleSystem.addParticle();
  particleSystem.run();
};
Galiba, küçük bir problemimiz var. applyForce() Particle nesnesinin içinde yazılan bir yöntemdir, ama parçacıkların kendisinden bahsetmemektedir, sadece particleSystem nesnesinden bahsetmektedir:particleSystem değişkeni.
Tüm parçacıkların kuvveti almasını istediğimizde, parçacık sistemine kuvveti uygulamaya karar verebiliriz ve kuvveti tüm parçacıklara uygulamasını isteyebiliriz.
draw = function() {
  background(168, 255, 156);
  particleSystem.applyForce(wind);
  particleSystem.addParticle();
  particleSystem.run();
};
Elbette, draw()'daki ParticleSystem nesnesinde yeni bir fonksiyon çağırırsak, bu fonksiyonu ParticleSystem nesnesinde yazmamız gerekir. Fonksiyonun uygulaması gereken işi tanımlayalım: bir PVector kuvvetini alma ve bu kuvveti tüm parçacıklara uygulama.
Şimdi kodda:
ParticleSystem.prototype.applyForce = function(f){
  for(var i = 0; i < this.particles.length; i++){
    this.particles[i].applyForce(f);
  }
};
Bu işlevi yapmak saçma gibi görünüyor. Söylediğimiz şey şudur: “parçacık sistemine bir kuvvet uygulayın ki, sistem bu kuvveti tüm parçacıklara bireysel olarak uygulayabilsin.” Yine de gerçekten de oldukça makuldur. Ne de olsa, ParticleSystem nesnesi parçacıkların yönetiminden sorumludur, onun için parçacıklarla konuşmak istersek, onlarla yöneticisi vasıtasıyla konuşmamız gerekir.
Hepsini böyle birleştiriyoruz. Güneş kuvvetiyle oynayın, ve parçacık hareketini nasıl etkilediğine bakın, ve farklı kütlelerdeki parçacıklarına farklı tepkilerine dikkat edin. Bunun nedenini düşünün.

Yerçekimini ekleme

Şimdi daha karmaşık bir kuvveti uygulayalım, yerçekimi, bu da rüzgardan farklıdır çünkü uygulandığı nesnelerin kütlesine göre değişir.
İki kütle arasındaki yerçekimi kuvvetini hesaplma denklemini hatırlayalım:  F, start subscript, g, end subscript, with, vector, on top, equals, start fraction, G, m, start subscript, 1, end subscript, m, start subscript, 2, end subscript, divided by, vertical bar, vertical bar, r, vertical bar, vertical bar, squared, end fraction, r, with, hat, on top
Dünya üzerinde yerçekimi kuvvetini modellerken, dünyanın uyguladığı kuvvetin diğer çekim kuvvetlerinden çok üstün olduğu için onları gölgede bıraktığını unutmayın, onun için ilgilendiğimiz tek denklem, dünya ile nesne arasındaki yerçekimi kuvvetini hesaplayan denklemdir.G ve m, start subscript, 1, end subscript her parçacık için aynıdır, ve r(dünyadan yarıçapı) temelde aynıdır (çünkü parçacıkların dünyadan uzaklığına kıyasla dünyanın yarıçapı çok büyüktür), o nedenle, bunları dünyadaki yerçekimi g, olarak sadeleştiririz:
g, equals, start fraction, G, m, start subscript, 1, end subscript, divided by, vertical bar, vertical bar, r, vertical bar, vertical bar, squared, end fraction
Şimdi, yerçekimi kuvveti bir g sabiti çarpı parçacık kütlesi, çarpı kuvvetin yönünde bir birim vektördür (bu da hep aşağı doğru olur):
F, start subscript, g, end subscript, with, vector, on top, equals, g, m, start subscript, 2, end subscript, r, with, hat, on top
Kodda, bunun anlamı her parçacığa kütlesine göre farklı bir yerçekimi uygulamamız gerektiğidir. Bunu nasıl yapabiliriz? Mevcut applyForce fonksiyonunu yeniden kullanamayız, çünkü her parçacık için aynı kuvveti bekler. applyForce'un kütleyi çarpmasını hatırlatan bir parametre geçirmeyi düşünebiliriz, ama isterseniz bu fonksiyonu yalnız bırakalım ve mutlak bir sabit vektöre göre kuvvet hesaplayan yeni bir fonksiyon applyGravity, oluşturalım:
// Üstte belirtilen, sabit bir aşağı vektörü
var gravity = new PVector(0, 0{,}2);
ParticleSystem.prototype.applyGravity = function() {
    for(var i = 0; i < this.particles.length; i++) {
        var particleG = gravity.get();
        particleG.mult(this.particles[i].mass);
        this.particles[i].applyForce(particleG);
    }
};
Artık, bunların hepsini doğru yaptıysak, parçacıklarımızın hepsi, aşağıdaki simülasyonda aynı hızda düşmelidir. Bunun nedeni, yerçekimi kuvvetinin kütleyle çarpmaya bağlı olması, ancak ivmenin kütleye bölmeye bağlı olmasıdır, yani sonunda kütle etkisiz kalır. Bu kadar çaba sonucu etkisiz kalmak saçma gelebilir, ama birden çok farklı kuvveti birleştirdiğimizde önemli olacaktır.

İtici ekleme

Ya bunu bir aşama ileriye götürmeyi ve nesneler yaklaştıkça onları iten bir nesne eklemek istersek? Bu, daha önce oluşturduğumuz çeken nesneye benzerdir, sadece ters yönde itmektedir. Bir kez daha, yerçekimi gibi, her bir parçacık için farklı bir kuvver hesaplamamız gerekir, ama iticinin durumunda, aradaki fark, hesaplamanın kütleye değil, uzaklığa bağlı olmasıdır. Yerçekiminde, kuvvet vektörlerimizin hepsinin yönü aynıydı, ama iticide, kuvvet vektörlerinin hepsinin yönleri farklı olur:
Yerçekimi kuvveti : Bütün vektörler aynı yöndedir.
İtme kuvveti : Bütün vektörler farklı doğrultudadır.
İtici bir gücün hesaplanması yerçekiminin hesaplanmasından biraz daha karmaşık olduğundan (ve birden fazla itici isteyebiliriz!), bu problemi basit parçacık sistemimiz artı yerçekimi örneğine yeni bir Repeller nesnesi katarak çözeceğiz. Kodumuzda iki önemli ekleme gerekecek:
  1. Bir Repeller nesnesi (bildirilmiş, başlatılmış, ve gösterilen).
  2. Repeller nesnesini, her bir parçacık nesnesine kuvvet uygulaması için ParticleSystem'e geçirecek bir fonksiyon.
var particleSystem = new ParticleSystem(new PVector(width/2, 50));
var repeller = new Repeller(width/2-20, height/2);
var gravity = new PVector(0, 0{,}1);

draw = function() {
  background(214, 255, 171);

  // Tüm parçacıklara yer çekimi uygula
  particleSystem.applyForce(gravity);
  particleSystem.applyRepeller(repeller);
  repeller.display();
  particleSystem.addParticle();
  particleSystem.run();
};
Görüntülenebilir bir Repeller nesnesini yapmak kolaydır; daha önce oluşturduğumuz Attractor nesnesinin bir kopyasıdır:
var Repeller = function(x, y) {
  this.position = new PVector(x, y);
};

Repeller.prototype.display = function() {
  stroke(255);
  strokeWeight(2);
  fill(127);
  ellipse(this.position.x, this.position.y, 32, 32);
};
Daha zor olan soru, applyRepeller() yöntemini nasıl yazarız? PVector'u applyForce() gibi bir fonksiyona geçirmek yerine, bir Repeller nesnesini applyRepeller() fonksiyonuna ve bu fonksiyondan itici ve tüm parçacıklar arasındaki kuvveti hesaplamasını isteriz:
ParticleSystem.prototype.applyRepeller = function(r) {
  for(var i = 0; i < this.particles.length; i++){
    var p = this.particles[i];
    var force = r.calculateRepelForce(p);
    p.applyForce(force);
  }
};
Buradaki en büyük fark, her parçacık için yeni bir kuvvet hesaplanmasıdır, çünkü daha önce gördüğümüz gibi, kuvvet her parçacığın iticiye göre özelliklerine göre değişir. Bu kuvveti calculateRepelForce fonksiyonunu kullanarak hesaplarız, bu da Attractorlarımıza göre calculateAttractionForce fonksiyonunun tersidir.
Repeller.prototype.calculateRepelForce = function(p) {
  // Calculate direction of force
  var dir = PVector.sub(this.position, p.position); 
  // Distance between objects
  var d = dir.mag();
  // Yön vektörünü normalleştirin (burada uzaklık önemli değildir, bu vektörü sadece yön için istiyoruz)
  dir.normalize();
  // Uzaklığı makul bir aralıkta tutun
  d = constrain(d, 1, 100);    
  // Tepme kuvveti uzaklıkla ters orantılıdır
  var force = -1 * this.power/ (d * d);     
  // Kuvvet vektörünü alın --> büyüklük * yön
  dir.mult(force);                                  
  return dir;
};
Dikkat ederseniz, çevreye itici ekleme süreci boyunca, Particle nesnesini düzenlemeyi hiç düşünmedik. Bir parçacık, çevresinin detaylarını bilmek zorunda değildir; sadece konumunu, hızını, ve ivmesini yönetmesi, ve dış kuvveti alıp tepki verme becerisine sahip olması yeterlidir.
Artık bu örneğin tamamına bakabiliriz. Parçacıklara etki eden kuvvetlerin gücünü değiştirmeyi deneyin - yerçekimi ve itici - ve bunun, bunları nasıl değiştirdiğini görün: