A vektor olyan értékek gyűjtőhelye amik egy relatív helyzetet határoznak meg a térben. A két pont közé rajzolt nyíl a pontok közötti távolságot jelentik:

Bevezetés
Az első példában nem alkalmazunk még vektort, csak egy olyan mozgó, visszapattanó "labdát" rajzolunk, ami a következő tulajdonságokkal rendelkezik:
- van helyzete, x és y koordinátával
- sebessége, xseep és yspeed változókkal
- gyorsulása, xacceleration és yacceleration változókkal
- cél helyzete, xtarget és ytarget változóval
- hat rá a szél, xwind és ywind változókkal
- és hat rá a surlódás, xfriction és yfriction változókkal
2 dimenzióban ábrázoljuk, de ha 3d-ben akarnánk akkora z tengelyhez is be kellene vezetnünk a változókat.

float x = 100;
float y = 100;
float xspeed = 1;
float yspeed = 3.3;
void setup() {
size(200,200);
smooth();
background(255);
}
void draw() {
noStroke();
fill(255,10);
rect(0,0,width,height);
// pozíció változtatása a sebességgel:
x = x + xspeed;
y = y + yspeed;
// visszapattanás beállítása:
if ((x > width) || (x < 0)) {
xspeed = xspeed * -1;
}
if ((y > height) || (y < 0)) {
yspeed = yspeed * -1;
}
// x,y helyzetben megjelenítjük a labdát:
stroke(0);
fill(175);
ellipse(x,y,16,16);
}
Ezen float változók helyett használhatunk PVectort is, akár fizikai szimulációhoz is jó. Most csak 2d-ben nézzük meg.
Mit jelentenek a vektorok?
Definíciója szerint a két pont közötti távolságot jelenti. Néhány példa a vektrok (mozgás) átfordítására. Korábban ezt a módszert használtuk ha el akartunk mozdítani egy pontot - meghatároztuk mennyivel mozduljon el x és y irányban:

Ezt lecserélhetjük vektorra, megmondhatjuk egyalakzatnak hogy A pontból B pontba mozduljon, az úgynevezett pixel-sebesség (pixel velocity) érték hozzáadásával:
location = location + velocity

Ha a sebességet egy vektorral adjuk meg, akkor a pozíciót is azzal kell meghatározni? Egyrészt a pozíció egy szimpla pont a térben. Másrészt meghatározható egy útvonal részeként is, ebben az esetben már vektroként is értelmezhetjük és létrehozhatunk egy olyan osztályt a mozgásnak, ami jóval kényelmesebb megoldás, mint egyes pontokat meghatározni.
Határozzunk meg értékeket a pozíciónak és a sebességnek. A pattogólabda példában ezt így csináltuk:
location --> x,y velocity --> xspeed,yspeed
Ugyanezt megtehetjükegy osztályon belül is:
class PVector {
float x;
float y;
PVector(float x_, float y_) {
x = x_;
y = y_;
}
}
DE a cél pozíció értékeket (float x és y helyett) megadhatjuk vektorban is:
PVector location = new PVector(100,100); PVector velocity = new PVector(1,3.3);
Ezek után már algoritmust is írhatunk ezekhez az értékekhez, a korábban használt x=x+speed helyett. A pillanatnyi gyorsulás értéket hozáadjuk a pillanatnyi pozícióhoz:
location = location + velocity;
Habár a + művelet csak primitív értékekkel működik Processingben. Így afenti sort nem tudja értelmezni, ezért a meghatározott függvényekkel tudunk matematikai műveleteket elvégezni: http://processing.org/reference/PVector.html
Vektorok összeadása: add()

u = (5,2)
v = (3,4)
(Vektor jelölése félkövér betűvel, vagy a betű feletti nyíllal. Valós számok dőlt betűvel.)
Minden vektornak két eleme van, x és y érték. Ha két vektort össze akarunk adni akkor az x és az y értékeiket kell összeadnunk:
w = u + v esetén:
wx = ux + vx
wy = uy + vy
ebben az esetben:
wx = 5 + 3
wy = 2 + 4
w = (8,6)

PVector-ok összeadása esetén az add() függvényt tudjuk erre használni. Pontszintaxissal működik. Szintaxisa.
Az előző pattogó labda példa átírása vektor összeadással:
Example: Bouncing Ball with PVector!
// float helyett vektort használunk:
PVector location;
PVector velocity;
void setup() {
size(200,200);
smooth();
background(255);
location = new PVector(100,100);
velocity = new PVector(2.5,5);
}
void draw() {
noStroke();
fill(255,10);
rect(0,0,width,height);
// pillanatnyi sebességet a pozícióhoz adjuk:
location.add(velocity);
// A vektorok értékeit pont szintaxissal érjük el,
// (location.x, velocity.y, stb.)
if ((location.x > width) || (location.x < 0)) {
velocity.x = velocity.x * -1;
}
if ((location.y > height) || (location.y < 0)) {
velocity.y = velocity.y * -1;
}
// kör megjelenítése x pozícióban:
stroke(0);
fill(175);
ellipse(location.x,location.y,16,16);
}
Az ellipse() fügvényben nem tudsz paraméternek megadni PVectort, mivel neki x és y érték is kell, ezért azokat az értékeket ki kell szedni, így:
ellipse(location.x,location.y,16,16);
Ugyanez igaz a for ciklusra is. A pl a location és a velocity vektor esetén:
if ((location.x > width) || (location.x < 0)) {
velocity.x = velocity.x * -1;
}
Még több algebra
- add() -- vektorok összeadása
- sub() -- vektorok kivonása
- mult() -- vektorok szorzása
- div() -- vektorok osztása
- mag() -- vektor terjedelmének/hosszának kiszámítása
- normalize() -- egység hosszúságúra normalizálja a vektort
- limit() -- limitálja a vektor terjedelmét/hosszát
- heading2D() -- a vektro iránya fokban kifejezve
- dist() -- az euklédészi* távolság két vektor között (pontban)
*http://wiki.prog.hu/wiki/Euklid%C3%A9szi_algoritmus_(algoritmus) - angleBetween() -- két vektoráltal bezárt szög
- dot() -- két vektor skaláris szorzata
- cross() -- két vektor vektorális szorzata
Vektorokról: http://aries.ektf.hu/~hz/pdf-tamop/pdf-01/html/ch01.html
Példa: Vektorok kivonása, egér mozgást követő vonal, a középpontja fix:

void setup() {
size(200,200);
smooth();
}
void draw() {
background(255);
// két PVector, az egyik az egér helyzete a másik az ablak közepe:
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
// PVector-ok kivonása
mouse.sub(center);
/*
// PVector osztás: // az eredeti méret fele lesz ha ezt is bele tesszük: mouse.mult(0.5);
*/
// ábrázoljuk a vektort, vonal kirajzolása:
translate(width/2,height/2);
line(0,0,mouse.x,mouse.y);
}
Vektor hossza: mag()

Pitagorasz tétel segítségével tudjuk meghatározni, amit a következő képlettel írható le:
||v|| = sqrt(vx*vx + vy*vy)
PVector-nál a mag() függvény felel meg ennek, pontszintaxissal működik. A következő példa balfelső sarokba rajzol egy a vektor aktuális hosszának megfelelő szélességű téglalapot:

void setup() {
size(200,200);
smooth();
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
mouse.sub(center);
//a vektor hosszát változóként meghatározzuk:
float m = mouse.mag();
fill(0);
rect(0,0,m,10);
translate(width/2,height/2);
line(0,0,mouse.x,mouse.y);
}
Normalizálás
Szabványosítja a vektort, egységnyi hosszúra alakítja.

A nagyságával osztjuk el a vektrort ilyenkor. (De 0-val nem oszthatjuk el! Nem működik.)

Példa:

void setup() {
size(200,200);
smooth();
}
void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
mouse.sub(center);
// normalizáljuk a vektort, majd megszorozzuk 50-nel
// Nem számít hol van az egér,mert fix lesz a vektor hossza,
// a normalizálásnak köszönhetően.
mouse.normalize();
mouse.mult(50);
translate(width/2,height/2);
line(0,0,mouse.x,mouse.y);
}
Mozgás
A pattogó labdánál meghatároztuk a labda helyzetét és sebességét és ezeket adtuk össze hogy megkapjuk a labda aktuális pozícióját.
location.add(velocity);
Ezután kirajzoltuk a labdát a megfelelő helyen:
ellipse(location.x,location.y,16,16);
Setupban és loopban határoztuk meg ezeket. Most ezeket tegyük át egy osztályba! (OOP) A két változót két vektorként defíniáljuk!
class Mover {
PVector location;
PVector velocity;
void update() {
///aktuálispozícióba mozgatás
location.add(velocity);
}
void display() {
////megjelenítés
stroke(0);
fill(175);
ellipse(location.x,location.y,16,16);
}
}
Ebből a kódból még hiányzik egy fontos rész, a konstruktor! Ugyanazon a néven, függvényben megadjuk:
Mover() {
location = new PVector(random(width),random(height));
velocity = new PVector(random(-2,2),random(-2,2));
}
Ugyanebben a "mozgó" osztályban határozzuk meg mi történjen ha az ibjektum az ablakunk széléhez ér! Ha kimegy az egyik oldalon jöjjön be a másikon egyből:
void checkEdges() {
if (location.x > width) {
location.x = 0;
} else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
} else if (location.y < 0) {
location.y = height;
}
}
Most hogy kész van az osztály, már hivatkozhatunk rá. Deklaráljuk:
Mover mover;
Setupban:
mover = new Mover();
Drawban:
mover.update();
mover.checkEdges();
mover.display();
TELJES PÉLDA

// Mover objektum deklarálása
Mover mover;
void setup() {
size(200,200);
smooth();
background(255);
// Mover objektum létre hozása
mover = new Mover();
}
void draw() {
noStroke();
fill(255,10);
rect(0,0,width,height);
// fügvények meghívása Mover objektumhoz:
mover.update();
mover.checkEdges();
mover.display();
}
class Mover {
//két PVectors: location-pozíció, velocity-sebesség:
PVector location;
PVector velocity;
Mover() {
location = new PVector(random(width),random(height));
velocity = new PVector(random(-2,2),random(-2,2));
}
void update() {
// mozgás:pozíció+sebesség
location.add(velocity);
}
void display() {
stroke(0);
fill(175);
ellipse(location.x,location.y,16,16);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
} else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
} else if (location.y < 0) {
location.y = height;
}
}
}
Ennél érdekesebb mozgást úgy érhetünk el ha a gyorsulásnak is megadunk egy PVektort, és ezt hozzáadjuk a sebességhez:
velocity.add(acceleration); location.add(velocity);
De használhatunk algoritmusokat is. Lehet a gyorsulás egyenletes vagy random, zajos vagy egérmozgásnak megfelelő is akár.
The source code contained in this tutorial is also available for download.
forrás: http://processing.org/learning/pvector/
