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

Jeżeli jesteś za filtrem sieci web, prosimy, upewnij się, że domeny *.kastatic.org i *.kasandbox.org są odblokowane.

Główna zawartość

Wzajemne przyciąganie

Mamy nadzieję, że pomogło Wam rozpoczęcie za pomocą prostego przykładu—jeden obiekt przyciąga inny obiekt— po czym skupiliśmy się na tym, aby jeden obiekt przyciągał wiele obiektów. Jednak, jest prawdopodobne, że często będziecie mieli styczność z bardziej skomplikowaną sytuacją: wiele obiektów przyciągających się nawzajem. Innymi słowy, każdy obiekt w zadanym systemie przyciąga każdy inny obiekt w tym systemie (poza sobą samym).
Już prawie posiadamy wszystko, co jest do tego potrzebne. Rozważmy program z tablicą obiektów Mover:
var movers = [];

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

draw = function() {
    background(255, 255, 255);
    for (var i = 0; i < movers.length; i++) {
        movers[i].update();
        movers[i].display();
    }
};
To w funkcji draw() będziemy musieli zawrzeć całą magię. Teraz, mówimy jej “dla każdego obiektu Mover i zaktualizuj i wyświetl samego siebie.” Teraz musimy sprawić, aby działał tak: “ dla każdego obiektu Mover, bądź przyciągany do każdego innego Movera, następnie zaktualizuj i wyświetl siebie.”
for (var i = 0; i < movers.length; i++) {
    // Dla każdego obiektu Mover, sprawdź wszystkie obiekty Mover!
    for (var j = 0; j < movers.length; j++) {
        var force = movers[j].calculateAttraction(movers[i]);
        movers[i].applyForce(force);
    }
}

for (var i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display();
}
Zauważ, że dodaliśmy nową pętle for przed pętlą aktualizuj-i-wyświetl. Musimy tak zrobić, aby mieć pewność, że obliczymy wszystkie siły przyciągania zanim będziemy aktualizować movery. Gdybyśmy przypadkowo zaktualizowali nasze movery w tej pierwszej pętli for , miałoby to wpływ na obliczenie sił przyciągania pomiędzy obiektami i wynik nie byłby dokładny.
Nasz kod nie będzie jeszcze działać, ponieważ każdy Mover musi mieć własną metodę calculateAttraction(). W poprzednich przykładach mieliśmy obiekt Attractor z metodą calculateAttraction(). Teraz, skoro obiekty Mover przyciągają siebie nawzajem, możemy skopiować tą metodę do wnętrza obiektu Mover.
Mover.prototype.calculateAttraction = function(m) {
  var force = PVector.sub(this.position, m.position);
  var distance = force.mag();
  distance = constrain(distance, 5.0, 25.0);                        
  force.normalize();

  var strength = (G * this.mass * m.mass) / (distance * distance);
  force.mult(strength);
  return force;
};
Oczywiście pojawia się mały problem. Gdy patrzymy na każdy obiekt oznaczony jako i oraz j, czy nie przeszkadza nam gdy i jest równe j? Dla przykładu czy trzeci obiekt Mover powinien przyciągać trzeci obiekt Mover? Oczywiście, nie. Jeżeli mamy pięć obiektów, chcemy aby Mover trzeci przyciągał obiekty 0,1,2 i 4, pomijając siebie. Chcemy jednak obliczać i używać siły z Movera trzeciego na pierwszym, oraz z pierwszego na trzecim. Obliczone siły będą takie same dla tej pary, ale wartość otrzymanego przyspieszenia będzie różna w zależności od masy tych obiektów. Nasza tabela przyciągania powinna wyglądać tak:
0 ⇢ 1, 2, 3, 4
1 ⇢ 0, 2, 3, 4
2 ⇢ 0, 1, 3, 4
3 ⇢ 0, 1, 2, 4
Tak więc kończymy ten przykład modyfikując naszą pętlę tak, aby wewnętrzna pętla zapobiegała sytuacji, gdy obiekt działa na siebie samego:
for (var i = 0; i < movers.length; i++) {
    for (var j = 0; j < movers.length; j++) {
       if (i !== j) {
         var force = movers[j].calculateAttraction(movers[i]);
         movers[i].applyForce(force);
       }
    }
}
Zobaczmy więc całość:

Ten kurs "Symulacje Natury" jest pochodną z "Natury Kodu " stworzonej przez Daniela Shiffmana, użytej pod licencją Creative Commons Attribution-NonCommercial 3.0 Unported License.

Chcesz dołączyć do dyskusji?

Na razie brak głosów w dyskusji
Rozumiesz angielski? Kliknij tutaj, aby zobaczyć więcej dyskusji na angielskiej wersji strony Khan Academy.