„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
| 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 | ||