Основно съдържание
Курс: Програмиране > Раздел 5
Урок 5: Сили- Закони на Нютон
- Предизвикателство: Реещ се балон
- Движение на много обекти
- Предизвикателство: Топки по стената
- Моделиране на гравитация и триене
- Предизвикателство: ограничители на скоростта
- Съпротива на въздух и флуид
- Предизвикателство: Потъващи дънери
- Гравитационно привличане
- Предизвикателство: Генератор на рисунки
- Взаимно привличане
- Предизвикателство: Взаимно отблъскване
- Проект: Приятни създания и страшни създания
© 2024 Khan AcademyУсловия за ползванеДекларация за поверителностПолитика за Бисквитки
Взаимно привличане
Надявам се, че ти беше полезно, че започнахме с прост сценарий – един обект привлича друг обект – и продължихме с това как един обект привлича много обекти. Все пак, вероятно ще се окажеш в доста по-сложна ситуация: много обекти се привличат един друг. С други думи всеки обект в дадена система привлича всеки друг обект в тази система (освен себе си).
Вече свършихме почти цялата работа за това. Да разгледаме програма с масив от обекти
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 every Mover, check every 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();
}
Забележи, че създадохме един напълно нов
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? Отговорът, разбира се, е "не". Ако има пет обекта, искаме обектът с номер 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
1 ⇢ 0, 2, 3, 4
2 ⇢ 0, 1, 3, 4
3 ⇢ 0, 1, 2, 4
И така, да завършим този пример, като променим нашия for цикъл, така че вътрешният цикъл да избягва собственото привличане на movers обектите:
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);
}
}
}
И да видим всичко заедно:
Курсът "Компютърни симулации на физични явления" е производeн на "Природата на кода" от Даниел Шифман, използвана от Creative Commons Attribution-NonCommercial 3,0 Unported License.
Искаш ли да се присъединиш към разговора?
Все още няма публикации.