თუ თქვენ ხედავთ ამ შეტყობინებას, ესე იგი საიტზე გარე რესურსების ჩატვირთვისას მოხდა შეფერხება.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

ძირითადი მასალა

ორმხრივი მიზიდულობა

იმედია, დაგეხმარათ მარტივი სცენარით დაწყება - ერთი ობიექტი იზიდავს სხვა ობიექტს - და გავაგრძელეთ შემდეგით: ერთი ობიექტი იზიდავს ბევრ ობიექტს. თუმცა, შეიძლება, უფრო რთულ სიტუაციაში აღმოჩნდეთ: ბევრი ობიექტი იზიდავს ერთმანეთს. სხვა სიტყვებით რომ ვთქვათ, მოცემულ სისტემაში ყველა ობიექტი იზიდავს ყველა სხვა ობიექტს ამ სისტემაში (საკუთარი თავის გარდა).
ამისათვის თითქმის მთელი სამუშაო შესრულებული გვაქვს. განვიხილოთ პროგრამა 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();
    }
};
draw() ფუნქციაში მცირეოდენი ოსტატობა დაგვჭირდება. ახლა ვამბობთ: „ყოველი i მოხეტიალისათვის, განაახლე და ეკრანზე გამოაჩინე შენი თავი“. უნდა ვთქვათ: „ყოველი i მოხეტიალისათვის, იყავი მიზიდული ყველა სხვა j მოხეტიალით, განაახლე და ეკრანზე გამოაჩინე შენი თავი“.
for (var i = 0; i < movers.length; i++) {
    // თითოეული მოძრავისთვის შევამოწმოთ თითოეული მოძრავი!
    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();
}
შევნიშნოთ, რომ ჩვენ გავაკეთეთ სრულიად ახალი for ციკლი განახლების და გამოჩენის ციკლის ზემოთ. ეს იმიტომ, რომ გვინდა, გამოვთვალოთ მიზიდულობის ყველა ძალა, სანამ განვაახლებთ თითოეულ მოხეტიალეს. თუ შემთხვევით განვაახლებდით თითოეულ მოხეტიალეს ამ პირველ for ციკლში, მაშინ ვიმოქმედებდით შემდეგ არსებული მიზიდულობის ძალების გამოთვლაზე და ეს არ იქნებოდა სწორი.
ჩვენი კოდი ჯერ არ იმუშავებს, რადგან გვჭირდება, რომ თითოეულ Mover-ს ჰქონდეს calculateAttraction() მეთოდი. წინა მაგალითში გვქონდა Attractor ობიექტი calculateAttraction() მეთოდით. ახლა, ვინაიდან გვაქვს მოხეტიალეები, რომლებიც იზიდავენ მოხეტიალეებს, შეგვიძლია, ეს მეთოდი გადავწეროთ 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;
};
რა თქმა უნდა, არის ერთი პატარა პრობლემა. როდესაც ვუყურებთ ყველა მოხეტიალე i-ს და ყველა მოხეტიალე j-ს, რას ვაკეთებთ იმ შემთხვევაში, როცა i უდრის j-ს? მაგალითად, მოხეტიალე #3-მა უნდა მიიზიდოს თუ არა მოხეტიალე #3? პასუხი, რა თქმა უნდა, არის — არა. თუ არის 5 ობიექტი, გვინდა, რომ მოხეტიალე #3-მა მიიზიდოს 0, 1, 2 და 4, გამოტოვოს თავისი თავი. მიუხედავად ამისა, გვინდა, რომ გამოვთვალოთ და გამოვიყენოთ ძალა მოხეტიალე #3-იდან მოხეტიალე #1-ზე და ძალა მოხეტიალე #1-იდან მოხეტიალე #3-ზე. გამოთვლილი ძალები ერთი და იგივე იქნება წყვილისათვის, მაგრამ მიღებული აჩქარება იქნება განსხვავებული, რომელიც დამოკიდებულია თითოეული მოხეტიალის მასაზე. ჩვენი მიზიდულობის ცხრილი უნდა გამოიყურებოდეს ასე:
0 ⇢ 1, 2, 3, 4
1 ⇢ 0, 2, 3, 4
2 ⇢ 0, 1, 3, 4
3 ⇢ 0, 1, 2, 4
ასე რომ, ამ მაგალითს ვასრულებთ ჩვენი for ციკლის შეცვლით ისე, რომ შიდა ციკლმა თავიდან აირიდოს მოხეტიალეების მიერ საკუთარი თავის მიზიდვა:
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);
       }
    }
}
ახლა ვნახოთ ყველაფერი ერთად:
ეს „ბუნებრივი სიმულაციების" კურსი ეფუძნება დანიელ შიფმენის წიგნს "კოდის ბუნებას", ის გამოყენებულია ლიცენზიით Creative Commons Attribution-NonCommercial 3,0 Unported License.

გსურთ, შეუერთდეთ დისკუსიას?

პოსტები ჯერ არ არის.
გესმით ინგლისური? დააწკაპუნეთ აქ და გაეცანით განხილვას ხანის აკადემიის ინგლისურენოვან გვერდზე.