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

თუ ვებფილტრს იყენებთ, დარწმუნდით, რომ *.kastatic.org და *.kasandbox.org დომენები არ არის დაბლოკილი.

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

გაზაფხულის ძალები

ამ სექციის დასაწყისში გადავხედეთ მარტივი ჰარმონიული მოძრაობის მოდელის შექმნას სინუსოიდური ტალღის პიქსელის დიაპაზონზე ასახვით, თქვენ შექმენით ტვირთის მოდელი ამ სინუსოიდური ტალღის გამოყენებით. sin() ფუნქცია არის „სწრაფი და ბინძური“, რაღაცის მიღებისა და გაშვების ერთხაზიანი გამოსავალი, მაგრამ ის არ გამოგვადგება, თუ გვინდა ისეთი ტვირთის ქონა, რომელიც ჩამოკიდებულია ზამბარაზე ორგანზომილებიან სივრცეში, რომელიც რეაგირებს სხვა ძალებზე გარემოში (ქარი, გრავიტაცია...). ამგვარი სიმულაციის მისაღწევად (რომელიც ქანქარის მაგალითის იდენტურია, უბრალოდ, ახლა მხარი არის ზამბარული კავშირი), უნდა შევქმნათ ზამბარის ძალების მოდელი PVector-ის გამოყენებით.
ზამბარის ძალა გამოითვლება ჰუკის კანონის მიხედვით (ეს სახელი მას რობერტ ჰუკის პატივსაცემად ჰქვია, ბრიტანელი ფიზიკოსის, რომელმაც შექმნა ფორმულა 1660 წელს).ჰუკმა კანონი ლათინურად ჩაწერა: „Ut tensio, sic vis", ანუ „რაც გაჭიმვა, ის ძალა." ამას ასე შევხედოთ:
ზამბარის ძალა ზამბარის დაჭიმულობის (წაგრძელების) პირდაპირპროპორციულია.
სხვა სიტყვებით რომ ვთქვათ, თუ ტვირთს ძალიან მოქაჩავთ, ძალა დიდი იქნება; თუ ტვირთს ოდნავ მოქაჩავთ, ძალა სუსტი იქნება. მათემატიკურად ეს კანონი შემდეგნაირად არის ჩამოყალიბებული:
F=k×x
  • k არის მუდმივა და მისი მნიშვნელობა საბოლოოდ დაასკალირებს ძალას. ზამბარა ძალიან დრეკადი ან ზედმეტად ხისტია?
  • x მიუთითებს ზამბარის გადაადგილებას, ანუ, სხვაობას ზამბარის მიმდინარე სიგრძესა და დაუჭიმავ მდგომარეობაში ყოფნის დროს სიგრძეზე. ზამბარის დაუჭიმავ მდგომარეობაში ყოფნის დროს სიგრძე ნიშნავს იმ სიგრძეს, რომელიც ზამბარას გააჩნია წონასწორობის მდგომარეობაში ყოფნისას.
გავიხსენოთ, რომ ძალა არის ვექტორი, ამიტომ უნდა გამოვთვალოთ ორივე — სიგრძე (სიდიდე) და მიმართულება. ახლა შევხედოთ ზამბარის კიდევ ერთ დიაგრამას და ყველა იმ მოცემულობას დავაწეროთ სახელი, რომელიც შეიძლება, პროგრამაში გვქონდეს.
შევქმნათ 3 საწყისი ცვლადი (როგორც ზემოთ მოცემულ დიაგრამაზეა ნაჩვენები) ადეკვატური მნიშვნელობებით.
var anchor = new PVector(100, 10);
var bob = new PVector(110, 100);
var restLength = 20;
პირველ ყოვლისა, გამოვიყენოთ ჰუკის კანონი ძალის სიდიდის გამოსათვლელად. უნდა ვიცოდეთ k და x. k ადვილია; ის მხოლოდ მუდმივაა, ამიტომ ჩვენით მოვიფიქროთ.
var k = 0{,}1;
x ცოტა უფრო რთულია. უნდა ვიცოდეთ „სხვაობა მიმდინარე სიგრძესა და დაუჭიმავ მდგომარეობაში ყოფნის დროს სიგრძეს შორის". დაუჭიმავ მდგომარეობაში ყოფნის დროს სიგრძე განსაზღვრულია ცვლადად, რომლის სახელია restLength. რა არის მიმდინარე სიგრძე? მანძილი სამაგრსა და ტვირთს შორის. და როგორ გამოვთვალოთ ეს მანძილი? რას იტყვით ვექტორის სიგრძეზე, რომელიც მიმართულია სამაგრიდან ტვირთისკენ? (აღვნიშნოთ, რომ ეს არის ზუსტად იგივე პროცესი, რომელიც გამოვიყენეთ მანძილის გამოთვლისას გრავიტაციული მიზიდვის სექციაში).
var dir = PVector.sub(bob, anchor);
var currentLength = dir.mag();
var x = currentLength - restLength;
ახლა, როცა გავარკვიეთ საჭირო ელემენტები ძალის სიდიდისათვის (-1 * k * x), უნდა გავარკვიოთ მიმართულება — ერთეულოვანი ვექტორი, რომელსაც იგივე მიმართულება გააჩნია, რაც ძალას. კარგი ამბავი ისაა, რომ ჩვენ უკვე გვაქვს ეს ვექტორი. არა? სულ ცოტა ხნის წინ ვიფიქრეთ: „როგორ გამოვთვალოთ ეს მანძილი? რას იტყვით ვექტორის სიდიდეზე, რომელიც მიმართულია სამაგრიდან ტვირთამდე?“ სწორედ ეს ვექტორი არის ძალის მიმართულება!
ზემოთ მოცემულ დიაგრამაზე ვხედავთ, რომ თუ ზამბარას დავჭიმავთ საწყის სიგრძეზე (დაუჭიმავ მდგომარეობაში ყოფნისას მქონე სიგრძეზე) მეტად, უნდა არსებობდეს ძალა, რომელიც სამაგრისკენ ეზიდება მას. ხოლო თუ მის სიგრძეს საწყის სიგრძესთან შედარებით შევამცირებთ, ძალამ უნდა იმოქმედოს მასზე სამაგრის საწინააღმდეგო მიმართულებით. მიმართულების ეს შებრუნება ფორმულაში აღირიცხება -1-ით. და ახლა გვჭირდება იმ PVector-ის ნორმალიზება, რომელიც გამოვიყენეთ მანძილის გამოსათვლელად! შევხედოთ კოდს და ამ PVector-ის ცვლადს დავარქვათ „force" (ძალა).
var k = 0{,}01;
var force = PVector.sub(bob, anchor);
var currentLength = force.mag();
var x = currentLength - restLength;
// დრეკადობის ძალის მიმართულება, ერთეულოვანი ვექტორი
force.normalize();
// ყველაფრის თავმოყრა: მიმართულება და სიდიდე (სიგრძე)!
force.mult(-1 * k * x);
ახლა, როცა გვაქვს ალგორითმი ზამბარის ძალის ვექტორის გამოსათვლელად, კითხვა შემდეგია: ობიექტზე ორიენტირებული პროგრამირების რომელი სტრუქტურა უნდა გამოვიყენოთ? ეს, კიდევ ერთხელ, არის მომენტი, როცა არ არსებობს „სწორი“ პასუხი. არსებობს მრავალი ვარიანტი; რომელს ავირჩევთ? ეს დამოკიდებულია კონკრეტული პროგრამის მიზნებსა და პროგრამისტის კოდის წერის სტილზე. და მაინც, ვინაიდან ჩვენ ვმუშაობდით Mover ობიექტით, მოდით, ამავე სამუშაო გარსით გავაგრძელოთ მუშაობა. ვიფიქროთ ჩვენს Mover ობიექტზე, როგორც ზამბარის „ტვირთზე“. ტვირთს ესაჭიროება ადგილმდებარეობის, სიჩქარისა და აჩქარების ვექტორები ეკრანის ირგვლივ მოძრაობისათვის. მშვენიერია, ჩვენ ეს უკვე გვაქვს! და, ალბათ, ტვირთზე მოქმედებს გრავიტაციის ძალა applyForce() მეთოდით. კიდევ მხოლოდ 1 ნაბიჯი — უნდა ვიმოქმედოთ ზამბარის ძალით:
var bob = new Bob();

draw = function()  {
  // Our “make-up-a-gravity force”
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // უნდა გამოვთვალოთ და გამოვიყენოთ დრეკადობის ძალაც!
  var spring = ????
  bob.applyForce(spring);

  // ჩვენი სტანდარტული update() (განახლების) და display() (ეკრანზე ჩვენების) მეთოდები
  bob.update();
  bob.display();
};
ერთი ვარიანტი არის დრეკადობის ძალის მთელი კოდის მთავარ draw() ციკლში სრულად ჩაწერა. მაგრამ მომავლისთვის, როცა შეიძლება, ბევრი ტვირთი და ზამბარის ბევრი გადაბმის წერტილი გვქონდეს, ჭკვიანურია, რომ დავწეროთ დამატებითი ობიექტი — Spring (ზამბარა) ობიექტი. როგორც ქვემოთ მოცემულ დიაგრამაზეა ნაჩვენები, Bob (ტვირთი) ობიექტი თვალყურს ადევნებს ტვირთის მოძრაობას; Spring ობიექტი თვალყურს ადევნებს ზამბარის სამაგრს და მის სიგრძეს დაუჭიმავობის დროს და გამოთვლის დრეკადობის ძალას ტვირთზე.
ეს საშუალებას გვაძლევს, ყველაფერს ერთად მოვუყაროთ თავი ამ ლამაზ კოდში:
var bob = new Bob();
var spring = new Spring();

draw = function()  {
  // ჩვენი შექმნილი გრავიტაციის ძალა
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // Spring.connect() იზრუნებს 
  // დრეკადობის ძალის გამოთვლასა და გამოყენებაზე
  spring.connect(bob);

  // ჩვენი სტანდარტული update() და display() მეთოდები
  bob.update();
  bob.display();
};
ალბათ, შეამჩნევდით, რომ ეს ძალიან ჰგავს იმას, რაც გავაკეთეთ გრავიტაციის სექციაში მიმზიდველთან. იქ შემდეგნაირი რაღაც ვთქვით:
var force = attractor.calculateAttraction(mover);
mover.applyForce(force);
ანალოგიური სიტუაცია ზამბარის შემთხვევაში შემდეგი იქნებოდა:
var force = spring.calculateForce(bob);
bob.applyForce(force);
ამ მაგალითში მხოლოდ შემდეგი რამ გავაკეთეთ:
spring.connect(bob);
რა ხდება? რატომ არ გვჭირდება applyForce()-ის გამოძახება ტვირთზე? პასუხი, რა თქმა უნდა, ისაა, რომ ჩვენ გვჭირდება applyForce()-ის გამოძახება ტვირთზე. უბრალოდ, ამის draw()-ში გაკეთების ნაცვლად, ვაჩვენებთ, რომ სრულიად ლოგიკური (და ზოგჯერ უპირატესი) ალტერნატივა არის, ვთხოვოთ connect() მეთოდს, რომ მან მიხედოს ტვირთზე applyForce()-ის გამოძახებას.
Spring.prototype.connect(bob) {
  var force = /* რამდენიმე მაგარი გამოთვლა */;
  bob.applyForce(force);
};
რატომ უნდა გავაკეთოთ ეს ერთი გზით Attractor ობიექტის შემთხვევაში, მაგრამ სხვა გზით Spring ობიექტის შემთხვევაში? როდესაც პირველად ვსწავლობდით ძალებს, ცოტა უფრო მეტად გასაგები იყო ყველა ძალის ჩვენება, რომლებსაც ვიყენებდით მთავარ draw() ციკლში და, იმედია, ეს დაგეხმარათ ძალების დაგროვების შესახებ სწავლაში. ახლა, როცა უკეთ ვიცნობთ მას, უფრო ადვილია ზოგიერთი დეტალი თვითონ ობიექტებში ჩავაშენოთ.
ყველაფერი ერთად მოვათავსოთ ქვემოთ ჩასმულ პროგრამაში. ჩვენ რამდენიმე რაღაც დავამატეთ: (1) Bob ობიექტი მოიცავს ფუნქციებს მაუსის ინტერაქციულობისთვის, რათა ტვირთის ეკრანზე გადატანა იყოს შესაძლებელი, და (2) Spring ობიექტი მოიცავს ფუნქციას გადაბმის სიგრძის შესაზღუდად მინიმუმსა და მაქსიმუმს შორის.
ეს „ბუნებრივი სიმულაციების" კურსი ეფუძნება დანიელ შიფმენის წიგნს "კოდის ბუნებას", ის გამოყენებულია ლიცენზიით Creative Commons Attribution-NonCommercial 3,0 Unported License.

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

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