„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés

Rohamcsiga (vitalap | szerkesztései)
Rohamcsiga (vitalap | szerkesztései)
217. sor: 217. sor:
* Az animáció onnantól kezd bonyolultá válni, hogy ha több mozgó test állapota egymástól függ (pl: mikor ütköznek). Ilyenkor ugyanis a korrekt szimuláció egy differenciálegyenlet megoldását jelentené. Ennek egy egyszerű közelítése a diszkrét idő-szimuláció, ahol az ötlet az, hogy válasszunk egy időegységet, amennyi idő alatt a testek állapota csak minimálisan változik meg, ez tipikusan pár milliszekundum, és legfeljebb ilyen időközönként kiválasztott statikus pillanatokban vizsgáljuk csak az egymásrahatásokat. Manapság a számítógépes játékok nagyrésze is ezt a módszert használja.
* Az animáció onnantól kezd bonyolultá válni, hogy ha több mozgó test állapota egymástól függ (pl: mikor ütköznek). Ilyenkor ugyanis a korrekt szimuláció egy differenciálegyenlet megoldását jelentené. Ennek egy egyszerű közelítése a diszkrét idő-szimuláció, ahol az ötlet az, hogy válasszunk egy időegységet, amennyi idő alatt a testek állapota csak minimálisan változik meg, ez tipikusan pár milliszekundum, és legfeljebb ilyen időközönként kiválasztott statikus pillanatokban vizsgáljuk csak az egymásrahatásokat. Manapság a számítógépes játékok nagyrésze is ezt a módszert használja.
* Egyszerű példaprogram: [http://pastebin.com/7FHzfjA7 Pattogó labda]
* Egyszerű példaprogram: [http://pastebin.com/7FHzfjA7 Pattogó labda]
<br/> <syntaxhighlight lang="c">
const float ball_radius = 0.1f;
Vector ball_pos, ball_speed(-0.46f, 1.13f);
void onIdle() {
  static int last_time = glutGet(GLUT_ELAPSED_TIME); // Visszaadja a jelenlegi időt miliszekundumban
  int curr_time = glutGet(GLUT_ELAPSED_TIME);
  int diff = curr_time - last_time; // Az előző onIdle óta eltelt idő
  last_time = curr_time; // A következő meghíváskor az előző idő majd a mostani idő lesz.
  // Két onIdle között eltelt idő nagyon változó tud lenni, és akár elég nagy is lehet
  // ahhoz, hogy a labda látványosan bele menjen a falba, mielőtt visszapattan. Ezért
  // osszuk fel az elelt időt kisebb részekre, pl. max 5 miliszekundumos egységekre,
  // és ilyen időközönként nézzük meg, hogy a labda ütközött-e a fallal.
  const int time_step = 5;
  for(int i = 0; i < diff; i += time_step) {
    // Az időosztás végén egy kisebb egység marad, mint az idő egység. Pl. ha a diff 11,
    // akkor azt akarjuk, hogy 5, 5, 1 egységekre bontsuk azt, ne 5, 5, 5-re.
    // Meg is kell számolnunk másodperce, azaz osztanunk kell 1000-el.
    float dt = min(diff-i, time_step) / 1000.0f;
    // Módosítsuk a sebességet ha ütközött a fallal, teljesen rugalmas ütközést feltételezve.
    // Ilyenkor a labda a fal irányára merőlegesen pontosan ellentétes irányba halad tovább.
    if(ball_pos.x + ball_radius > 1) {
      ball_speed.x = -fabs(ball_speed.x);
    } else if(ball_pos.x - ball_radius < -1) {
      ball_speed.x = fabs(ball_speed.x);
    }
    if(ball_pos.y + ball_radius > 1) {
      ball_speed.y = -fabs(ball_speed.y);
    } else if(ball_pos.y - ball_radius < -1) {
      ball_speed.y = fabs(ball_speed.y);
    }
    // Mozgassuk a labdát a ds = v * dt képlet alapján.
    ball_pos += ball_speed * dt;
  }
  glutPostRedisplay(); // Megváltozott a jelenet, újra kell rajzolni
}
</syntaxhighlight> <br/>
Az eredménye:
<div style="text-align:left;margin:0px auto;">
<div style="text-align:left;margin:0px auto;">
http://i.imgur.com/ezFQ4l4.png
http://i.imgur.com/ezFQ4l4.png