Sunčev sistem u 3D Processing-u – hijerarhijske transformacije

Lekcija 14 od 14 · Processing

U ovoj lekciji prelazimo na napredniji koncept 3D grafike – hijerarhijske transformacije. To znači da objekti mogu da budu “roditelji” i “deca”, pa njihovo kretanje zavisi od strukture sistema.

Na praktičnom primeru Sunčevog sistema videćemo kako se planeta može kretati oko Sunca, a mesec oko planete, koristeći samo transformacije i matricni sistem.

U ovoj lekciji naučićete:
  • kako funkcionišu hijerarhijske transformacije
  • kako se prave orbite planeta
  • kako se koristi rotate + translate za kretanje
  • kako se kreiraju 3D scene sa teksturama
  • kako se kombinuju kamera i osvetljenje

Koncept – Sunčev sistem kao hijerarhija

U 3D grafici svaki objekat može imati “dete” koje nasleđuje njegovu transformaciju. U ovom primeru:

  • Sunce → centar sistema
  • Zemlja → rotira oko Sunca
  • Mesec → rotira oko Zemlje
Ključna ideja:

Kada se Sunce ne pomera, ali se Zemlja rotira oko njega, to je rezultat kombinacije rotate() i translate() transformacija.

Interaktivna 3D animacija

Sledeća animacija prikazuje Sunčev sistem u realnom vremenu. Planete se kreću po orbitalnim putanjama i rotiraju oko svoje ose.

3D Sunčev sistem – p5.js simulacija

Ako animacija ne radi, osvežite stranicu (refresh).

Kako funkcioniše kretanje planeta?

Svaka planeta ima dva kretanja:

  • orbitalno kretanje – oko Sunca
  • rotacija oko ose – sopstvena rotacija

Ova dva kretanja se kombinuju pomoću uglova koji se stalno povećavaju u draw() funkciji.

Matematička ideja:

  • angle += speedRotation → orbita
  • angleOwn += speedOwnRotation → rotacija

Važan koncept – hijerarhijske transformacije

Zemlja se ne pomera “nezavisno”, već u odnosu na Sunce. To se postiže tako što se transformacije “nasleđuju” kroz sistem objekata.

Hijerarhija:

Sunce → Zemlja → Mesec

Svaki sledeći objekat koristi koordinatni sistem prethodnog.
Mogući problem (bug):

Ako se objekti ponašaju “čudno” ili nestaju iz scene, najčešći uzrok je pogrešan redosled transformacija ili nedostatak push()/pop() blokova.

Kontrola kamere

Kamera se može pomerati pomoću tastature:

  • ← → pomeranje po X osi
  • ↑ ↓ zoom (Z osa)
  • Q / W pomeranje po Y osi

Šta smo naučili?

  • Kako funkcionišu orbite u 3D prostoru
  • Kako se koristi hijerarhija objekata
  • Kako se kombinuju transformacije (translate, rotate)
  • Kako se pravi realna simulacija Sunčevog sistema
Sledeća lekcija

U narednoj lekciji prelazimo na napredne 3D koncepte: kamera u pokretu, interakcija sa mišem i generisanje kompleksnih scena.

Da bi smo kreirali 3D objekte u processing-u možemo to uraditi na nekoliko načina:

  1. koristiti ugrađene metode processing-a za crtanje osnovnih 3d oblika:
  2. Koristiti klasu PShape
  3. Samostalno kreirati oblik koristeći: beginShape().....endShape()

Crtanje osnovnih 3D oblika pomoću Processingovih metoda

Na ovaj način možemo kreirati osnovne oblike: lopta, kocka:

Metode koje se koriste:

  • sphere(R)-crta loptu(sferu), gde je R-poluprečnik
  • box(a)- crta kocku stranice a

Animacija 3D: Kretanje zemlje oko sunca - processing

Animacija kretanja Zemlje oko Sunca je prikazana ispod. Pri tome Zemlja vrši dve rotacije:

  • rotacija Zemlje oko Sunca
  • rotacija Zemlje  oko svoje ose
Interaktivna animacija: pokreni simulaciju u pregledaču – kosi-hitac.onrender.com/sunce_zemlja_mesec_animacija (p5.js verzija).

Kretanje Zemlje oko Sunca animacija 3d - kod u processing-u

U sledećem članku je opisano kako se kreira ova animacija upotrebom javascript biblioteke p5.js: kosi-hitac.onrender.com/sunce_zemlja_mesec_animacijaU animaciji rotacije Zemlje oko Sunca koristi se klasa PShape, kao što se može videti u kodu na slici 1. Da bi se kreirala tekstura slike, potrebno je ubaciti slike koje ćemo koristiti za teksturu zemlje i sunca i to u data folder, koji se nalazi u korenom folderu aplikacije. Unutar glavnog scatch-a definišu se objekti klase PImage, sunceIm i zemljaIm, koji će predstavljati slike za kreiranje teksture. Zatim se deklarišu konstante, koje redom predstavljaju poluprečnike Zemlje, Sunca i 2 poluose elipse, koja predstavlja putanju Zemlje oko Sunca. Takođe se definišu i promenljive koje se koriste za definisanje položaja kamere u x, y i z pravcu i uglovi rotacije

fiZ - ugao rotacije Zemlje oko svoje ose

fiS - ugao rotacije Zemlje oko Sunca

wiz- ugaona brzina rotacije Zemlje oko svoje ose

wis - ugaona brzina rotacije Zemlje oko Sunca

Brzina rotacije Zemlje je proizvoljna i ne odgovara stvarnim vrednostima, već je modifikovana da bi kretanje zemlje moglo da se uoči.

Unutar setup metode se kreiraju objekti Zemlje i Sunca, slike Zemlje i Sunca.

Tekstura se na objekat postavlja sa setTexture(slika) metodom, gde se slika prosleđuje metodi kao parametar.

Kod sa slike 1: Processing 3D: Animacija kretanja Zemlje oko Sunca. Glavni scatch

PShape sunce;
PShape zemlja;
PImage zemljaIm;
PImage sunceIm;
PImage pozadina;
static final float Rz = 25;     // poluprečnik Zemlje
static final float Rs = 80;     // poluprečnik Sunca
static final float Rp1 = 600;   // prečnici putanje Zemlje
static final float Rp2 = 600;
float camX = 0;                 // položaj kamere
float camY = -150;
float camZ = 500;
float fiz = 0;                  // ugao rotacije Zemlje oko svoje ose
float fis = 0;                  // ugao rotacije Zemlje oko Sunca
float wz = 0.03;                // ugaone brzine
float wzs = -0.005;

void setup() {
  size(1000, 600, P3D);
  noStroke();
  pozadina = loadImage("svemir1.jpg");
  sunce = createShape(SPHERE, Rs);
  zemlja = createShape(SPHERE, Rz);
  sunceIm = loadImage("sunce.jpg");
  zemljaIm = loadImage("zemlja.jpg");
  sunce.setTexture(sunceIm);
  zemlja.setTexture(zemljaIm);
}

U draw() metodi prvo se postavi pozadinska slika, svemira u ovom primeru. Kordinatni sistem se translira na sredinu okvira, metodom translate(width/2,height/2,0). Vidimo da je z koordinata postavljena na nulu.

Kamera se zatim postavi na koordinate camX, camY i camZ, a fokus kamere je u centru koordinatnog sistema. Sa poslednja 3 parametra se definiše koja se koordinatna osa nalazi na vrhu prikaza i to je u ovom slučaju z osa.

Za lepši prikaz koristi se usmerena svetlost directionalLight(), približno bele boje i koja je usmerena između pravca x i z ose i to u negativnom smeru.

Kod sa slike 2: Processing 3D: Animacija kretanja Zemlje oko Sunca. Glavni scatch-2. Draw metoda

void draw() {
  pozadina.resize(1000, 600);
  background(pozadina);
  translate(width / 2, height / 2, 0);
  camera(camX, camY, camZ, 0, 0, 0, 0, 0, 1);

  directionalLight(255, 255, 100, -1, 0, -1);
  shape(sunce);

  pushMatrix();
  stroke(255, 255, 150);
  noFill();
  rotateX(HALF_PI);
  ellipse(0, 0, Rp1, Rp2);      // putanja Zemlje
  popMatrix();

  rotateY(fis);

  pushMatrix();
  translate(Rp1 / 2, 0);
  rotateY(fiz);

  shape(zemlja);
  popMatrix();

  fiz += wz;
  fis += wzs;
}

Unutar transliranog koordinatnog sistema koji je sada u centru prikaza, renderuje se Sunce, pozivom metode shape(sunce), kojoj se prosleđuje prethodno kreirani objekat koji predstavlja sunce i klase je PShape. Zatim se crta eliptična putanja koja se crta u ravni X0Y i koja se privremeno zarotira za ugao PI/2 oko X ose(rotateX(HALF_PI)). Posle iscrtavanja, tj. posle poziva popMatrix(), vidi liniju 46, slika 2, koordinatni sistem se vraća u položaj u kojem je bio pre poziva pushMatrix(), metode koja je pozvana u liniji 41, vidi sliku 2.

Pre nego što se iscrta objekat koji predstavlja planetu Zemlju, koordinatni sistem se rotira oko Y ose za ugao fis, koji zapravo predstavlja ugao rotacije Zemlje oko Sunca.

Kod sa slike 3: Processing 3D: Animacija kretanja Zemlje oko Sunca. Glavni scatch-3. Metoda keyPressed()

void keyPressed() {
  if (keyCode == UP) {
    camZ -= 5;
  }
  if (keyCode == DOWN) {
    camZ += 5;
  }
  if (keyCode == LEFT) {
    camX -= 5;
  }
  if (keyCode == RIGHT) {
    camX += 5;
  }
  if (key == 'q') {
    camY -= 5;
  }
  if (key == 'w') {
    camY += 5;
  }
}
Ceo program u jednom komadu (3 slike spojene)
PShape sunce;
PShape zemlja;
PImage zemljaIm;
PImage sunceIm;
PImage pozadina;
static final float Rz = 25;     // poluprečnik Zemlje
static final float Rs = 80;     // poluprečnik Sunca
static final float Rp1 = 600;   // prečnici putanje Zemlje
static final float Rp2 = 600;
float camX = 0;                 // položaj kamere
float camY = -150;
float camZ = 500;
float fiz = 0;                  // ugao rotacije Zemlje oko svoje ose
float fis = 0;                  // ugao rotacije Zemlje oko Sunca
float wz = 0.03;                // ugaone brzine
float wzs = -0.005;

void setup() {
  size(1000, 600, P3D);
  noStroke();
  pozadina = loadImage("svemir1.jpg");
  sunce = createShape(SPHERE, Rs);
  zemlja = createShape(SPHERE, Rz);
  sunceIm = loadImage("sunce.jpg");
  zemljaIm = loadImage("zemlja.jpg");
  sunce.setTexture(sunceIm);
  zemlja.setTexture(zemljaIm);
}
void draw() {
  pozadina.resize(1000, 600);
  background(pozadina);
  translate(width / 2, height / 2, 0);
  camera(camX, camY, camZ, 0, 0, 0, 0, 0, 1);

  directionalLight(255, 255, 100, -1, 0, -1);
  shape(sunce);

  pushMatrix();
  stroke(255, 255, 150);
  noFill();
  rotateX(HALF_PI);
  ellipse(0, 0, Rp1, Rp2);      // putanja Zemlje
  popMatrix();

  rotateY(fis);

  pushMatrix();
  translate(Rp1 / 2, 0);
  rotateY(fiz);

  shape(zemlja);
  popMatrix();

  fiz += wz;
  fis += wzs;
}
void keyPressed() {
  if (keyCode == UP) {
    camZ -= 5;
  }
  if (keyCode == DOWN) {
    camZ += 5;
  }
  if (keyCode == LEFT) {
    camX -= 5;
  }
  if (keyCode == RIGHT) {
    camX += 5;
  }
  if (key == 'q') {
    camY -= 5;
  }
  if (key == 'w') {
    camY += 5;
  }
}

Pre crtanja Zemlje koordinatni sistem se translira za vrednost poluprečnika putanje Zemlje oko Sunca. Ovde je aproksimativno uzeto da je putanja kružna i ako je ona zapravo elipsa. Takođe se, dalje koordinatni sistem rotira za ugao fiz, tj. za ugao rotacije Zemlje oko svoje ose.

Na kraju draw() metode se uglovi rotacije fis i fiz povećaju za vrednosti ugaonih brzina, Zemlje oko Sunca i Zemlje oko svoje ose.

Proveri znanje

Otvori kviz

Kviz: Sunčev sistem u 3D

1. Šta su hijerarhijske transformacije?




2. Čemu služe pushMatrix() i popMatrix()?




3. Kako se Zemlja pomera na putanju oko Sunca?




4. Šta se povećava u svakom kadru da bi planete kružile?