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

Ако си зад уеб филтър, моля, увери се, че домейните *. kastatic.org и *. kasandbox.org са разрешени.

Основно съдържание

Въведение във вектори

В този курс ще наблягнем на всякакви начини за възприемане на света около нас и измислянето на хитри начини да симулираме този свят с код. Ще започнем с основна физика – как ябълката пада от дървото, как се люлее махалото във въздуха, как земята се върти около слънцето и т.н. Всичко, което ще обсъдим тук, изисква употребата на най-основното градивно блокче в програмиране на движение – векторът. И така, това е мястото, където започва нашата история.
Думата вектор може да означава много различни неща. Вектор е името на ню уейв рок група, създадена в Сакраменто, Калифорния, в началото на 1980. Това е името на зърнена закуска, произведена от Kellogg's Канада. В областта на епидемиологията вектор се използва за описание на организъм, който предава инфекция от един гостоприемник на друг. В езика за програмиране C++, вектор (std::vector) е реализация на динамично преоразмерим масив. Докато всички тези определения са интересни, те не са това, което търсим. Това, което търсим, се нарича евклидов вектор (наречен на гръцкия математик Евклид и също така известен като геометричен вектор). Когато видиш думата "вектор" в този курс, можеш да предположиш, че се отнася до евклидов вектор, определен като обект, който има големина и посока.
Векторът обикновено се визуализира като стрелка; посоката му се индикира от посоката, в която сочи стрелката, а големината – от дължината на самата стрелка.
Диаграма на вектор с величина и посока
Фигура 1,1: Вектор (начертан като стрелка) има големина (дължината на стрелка) и посока (накъде тя сочи).
В горната илюстрация векторът е начертан като стрелка от точка А до точка B и служи като инструкция за това как се пътува от А до B.

Защо да използваш вектори?

Преди да се впуснем в повече подробности за векторите, нека да разгледаме една проста програма, която показва защо въобще ни трябва да се интересуваме от векторите. Ако премина през уводния курс по JS тук в Кан Академия, вероятно в един момент научи как се пише проста програма – скачаща топка.
В горния пример имаме един много прост свят – празно платно с една кръгла форма ("топка"), която подскача наоколо. Тази топка има някои свойства, които са представени в кода като променливи.
ПозицияСкорост
x и yxSpeed и ySpeed
В една малко по-сложна програма можем да си представим, че ще имаме много повече променливи:
УскорениеМестоположение на целтаВятърТриене
xacceleration и yaccelerationxtarget и ytargetxwind и ywindxfriction и yfriction
Става все по-ясно, че за всяко понятие в този свят (вятър, местоположение, ускорение и т.н.), ще ни трябват две променливи. И това е просто един двумерен свят. За 3D свят ще ни трябват x, y, z, xspeed, yspeed, zspeed и т. н.
Нямаше ли да е чудесно, ако можехме да опростим нашия код и да използваме по-малко променливи?
Вместо:
var x = 5;
var y = 10;
var xSpeed;
var ySpeed;
Можем просто да имаме две променливи, където всяка променлива е подобен на вектор обект с информация в две измерения.
var position;
var speed;
След тази първа стъпка от използването на вектори няма да можем да правим нищо ново. Ако само решиш да използваш подобни на вектори обекти като променливи, няма да можеш магически да симулираш физика в своята програма. Въпреки това те ще опростят твоя код и ще ти предоставят набор от функции за общи математически операции, които да се случват отново и отново и отново, докато програмираш движение.
За да навлезем във векторите, ще си представим, че живеем в две измерения. Всички тези примери може сравнително лесно да се разширят до три измерения (ще използваме и обект – PVector – който дава възможност за три измерения.) Въпреки това ще ни е по-лесно да започнем само с две.

Програмиране с PVector

Един от начините, по който можем да си обясним един вектор, е чрез разликата между две точки. Помисли как можеш да дадеш инструкции за отиването от една точка до друга.
Ето няколко вектора и възможни транслации:
Диаграми на вектори
Фигура 1,2
| (-15, 3) | Направи 15 стъпки на запад; обърни се и направи 3 стъпки на север. | | (3, 4) | Направи 3 стъпки на изток; обърни се и направи 4 стъпки на север. | | (2, -1) | Направи 2 стъпки на изток; обърни се и направи 1 стъпка на юг. |
Вероятно се е случвало да правиш това и преди, когато се е случвало да програмираш движение. За всеки кадър от анимацията (например отделна итерация от цикъла за рисуване draw() на ProcessingJS), даваш инструкции на всеки обект на екрана да се премести с определен брой пиксели хоризонтално и определен брой пиксели вертикално.
Диаграма на използване на вектор за предстазване на новото местоположение
Фигура 1,3
За всеки кадър:
new position = velocity applied to current position
Ако скоростта е вектор (разликата между две точки), тогава какво е местоположението? Също ли е вектор? Технически, може да се спори, че местоположението не е вектор, тъй като то не описва как става движението от една точка до друга, а просто описва една отделна точка в пространството.
Въпреки това, друг начин да дефинираме местоположението е: пътят, изминат от началната точка до тази позиция. Това значи, че позицията може да бъде векторът, представящ разликата между позицията и началната точка.
Диаграма на местоположението като вектор
Фигура 1,4
Нека разгледаме данните за местоположение и скорост. В примера със скачащата топка имахме следното:
МестоположениеСкорост
x и yxspeed и yspeed
Забележи как съхраняваме едни и същи данни и за двете числа с плаваща запетая, x и y. Ако трябваше сами да напишем вектор клас, щяхме да започнем с нещо по-просто:
var Vector = function(x, y) {
  this.x = x;
  this.y = y;
};
В същността си, PVector е просто удобен начин за съхраняване на две стойности (или три, както ще видим в 3D примерите).
И така това...
var x = 100;
var y = 100;
var xspeed = 1;
var yspeed = 3{,}3;
се превръща в...
var location = new PVector(100,100);
var velocity = new PVector(1,3{,}3);
Сега щом вече имаме два векторни обекта за (местоположение и скорост), сме готови да имплементираме алгоритъм за движение: местоположение = местоположение + скорост. В пример 1,1, без вектори, ние имахме:
x = x + xspeed;
y = y + yspeed;
В един идеален свят ще успеем да пренапишем това по-горе като:
position = position + velocity;
Обаче в JavaScript операторът за събиране + е запазен само за примитивни стойности (числа, низове). В някои езици за програмиране операторите могат да бъдат "претоварени", но не и в JavaScript. За наш късмет обектът PVector включва методи за общи математически операции като събиране add().

Събиране на вектори

Преди да продължим да разглеждаме обекта PVector и неговия метод за събиране add(), нека разгледаме събирането на вектори с помощта от нотацията в учебниците по математика и физика.
Векторите обикновено се записват с удебелен шрифт или със стрелка на върха. За целите на тези уроци, трябва да се разграничим вектор от скалар (скалар се отнася до единична стойност, например цяло число или число с плаваща запетая), ще използваме нотация със стрелка:
  • Вектор: u
  • Скалар: x
Да речем, че имаме следните два вектора:
Диаграма на 2 вектора
фигура 1,5
Всеки вектор има два компонента – x и y. За да съберем два вектора, просто събираме техните компоненти x и y’s. 
Фигура 1,6
С други думи:
w=u+v
може да бъде записано като:
wx=ux+vxwy=uy+vy
След това вместо u и v с техните стойности от Фигура 1,6, получаваме:
wx=5+3wy=2+4
което означава, че:
wx=8wy=6
И накрая го записваме като вектор:
w=(8,6)
След като разбрахме как да съберем два вектора, можем да разгледаме как е имплементирано събирането в самия PVector обект. Нека напишем метод, наречен add(), който приема друг PVector обект като аргумент и просто събира компонентите x и y.
var Vector = function(x, y) {
  this.x = x;
  this.y = y;
};

Vector.prototype.add = function(v) {
  this.y = this.y + v.y;
  this.x = this.x + v.x;
};
След като видяхме как е написан add() в PVector, можем да се върнем към примера с нашата скачаща топка с нейния алгоритъм за местоположение + скорост и да имплементираме събирането на векторите:
location.add(velocity);
И сега вече сме готови да пренапишем примера със скачащата топка – например като използваме обекта PVector! Погледни кода и обърни внимание на разликите с кода от преди.
Трябва да отбележим важен момент от прехода към програмирането с вектори. Въпреки, че използваме PVector обекти, за да опишем две стойности – x и y на местоположението и x и y на скоростта, все още трябва да препращаме към x и y компонентите поотделно за всеки PVector. Когато трябва да начертаем даден обект в ProcessingJS, няма как да напишем:
ellipse(location, 16, 16);
Функцията ellipse() не приема PVector като аргумент. Елипса може да се начертае само с две скаларни стойности, x-координата и y-координата. И така ние трябва да се разровим в обекта PVector и да извадим x и y компонентите с помощта на обектно ориентирана точкова система:
ellipse(position.x, position.y, 16, 16);
Същият проблем възниква, когато кръгът достигне ръба на прозореца и ние трябва да достъпим отделните компоненти на двата вектора: местоположението location и скоростта velocity.
if ((position.x > width) || (position.x < 0)) {
  velocity.x = velocity.x * -1;
}
Може би чувстваш известно разочарование. В крайна сметка този преход към използване на вектори първоначално може да ти изглежда като излишно усложнение на кода от оригиналната версия. Това е напълно разумна и валидна критика, но е важно да разбереш, че все още не сме осъзнали пълната мощ на програмирането с вектори. Простата скачаща топка и прилагането на векторно събиране са само първите стъпки.
Колкото по-навътре навлизаме в сложния свят на множествата от обекти и сили (които ще въведем скоро), ползата от PVector ще стане по-ясна. Продължавай напред!

Курсът "Компютърни симулации на физични явления" е производeн на "Природата на кода" от Даниел Шифман, използвана от Creative Commons Attribution-NonCommercial 3,0 Unported License.

Искаш ли да се присъединиш към разговора?

Все още няма публикации.
Разбираш ли английски? Натисни тук, за да видиш още дискусии в английския сайт на Кан Академия.