I. Tamprios spyruoklės - Huko dėsnis (Hooke‘s Law)
Iš fizikos kurso ne
vienam teko susipažinti su Huko dėsniu tamprumo jėgoms, kurios atsiranda
deformuojant kūną, aprašyti. Gerai matyta dėsnio išraiška yra tokia:
Iš
dėsnio žinoma, kad deformuojant kūną, atsiranda priešinga deformacijai jėga
tiesiogiai proporcinga absoliučiam kūno pailgėjimui (ar sutrumpėjimui) x. Koeficientas
k – tamprumo koeficientas, k > 0, kuo k didesnis, tuo jėga didesnė ir
atvirkščiai. Minusas priekyje rodo, kad jėga yra priešingos krypties nei ta F‘,
kuria veikiame(spaudžiame) kūną.
Tamprumo jėga atsirandanti spaudžiant kūną |
Šios savybės gali
būti panaudojamos ten, kur reikalaujama šiek tiek tamprumo ir lankstumo –
virvėse ir drabužių simuliacijai. Kadangi jau prakalbau apie virves, tai
pabandysime išsiaiškinti visą tiesą apie jas!
II. Visa tiesa apie virtualias virves
Iš praktikos žinome, kad virvių būną įvairių – vienos standesnės, plonesnės/storesnės, lengvai arba negreit nutrūksta ir pan. Virvės lankstumas, tamprumas ir kitos savybės realybėje atsiranda tarpatominiame lygmenyje. Turint ribotus resursus tokį tikslumą kompiuteriu tiesiog neįmanoma pasiekti proto ir laiko ribose, todėl tenka sukčiauti. Virvę įsivaizduojame kaip segmentuotą atkarpą arba laužtę, kurios mazgai – kieti kūnai (rigid-bodies) tarp kurių veikia tamprumo ir kitos jėgos (virtualios spyruoklės).
Virvė kaip mazgų ir spyruoklių tarp jų sistema |
Tokią kietų kūnų
sistemą realizuoti paprasčiau, be to galima pasirinkti norimą
detalumą (segmentacijos laipsnį). Likę tarpai tarp mazgų užpildomi pagal
pageidavimus – tiesėmis, 3D geometrija (jei virvė trimatėje aplinkoje),
interpoliuojant Bezje (Bezier), cat-mull-rom splainais ir panašiai. Šiuo atveju
pasirinksime paprasčiausią būdą – mazgus jungsime tiesėmis. Taigi virvę galima
realizuoti kaip kietų kūnų eilę.
Tam, kad būtų galima
jau anksčiau realizuotą RigidBody klasę panaudoti virvės kūrimui, reikės ją papildyti
Huko dėsniu bei keliai kitais pakeitimais:
- Virvės mazge turėti informaciją apie prie jo prijungtus kitus mazgus
- Jėgų nustatymo metode be gravitacijos paskaičiuoti ir veikiančią tamprumo jėgą bei ją pridėti prie kūną veikiančių jėgų atstojamosios
- (Extra) Papildomai pridėti interaktyvumo pele, kad virvę būtų galima pajudinti
Visa tai realizuoti
lengviausia paveldint anksčiau sukurtą (praeitame straipsnyje) RigidBody klasę
ir papildyti naujais metodais ir kintamaisiais. Pilną realizaciją rasite pridėtame
kode straipsnio pabaigoje, o toliau iš arčiau pažvelkime į galimus iškilti keblumus
ir tam tikrus įgyvendinimo niuansus.
III. Huko dėsnis – praktiškai!
Realizuoti sistemą
šiek tiek pamąsčius atrodytų gal ir nesunku, jei ne tam tikros problemos. Viena
iš jų – Huko dėsnis nieko nekalba apie slopinimą, o be jo – sistema
išsiderintų, tamprumo jėgos paimtų viršų ar net virvės mazgai judėtų
nesustodami (be pusiausvyros)! Todėl praktiškai yra naudojamas šiek tiek
modifikuotas Huko dėsnis:
Naujoje formulėje
atsiranda spyruoklės ilgio apribojimas (maxLength – natūralus neištemptos
spyruoklės ilgis) bei papildomas greičio narys ir koeficientas: b – slopinimo koeficientas (damping
factor), b > 0. Slopinimo koeficientas (priklausomai nuo jo modulio) leidžia
realizuoti įvairias terpes, kurioje veikia spyruoklės. Didesnis slopinimo
koeficientas duoda didesnį stabilumą (mažesnį paslankumą) ir lėtesnį greičio
kitimą spyruoklėms (pavyzdžiui klampioje terpėje). Naudojantis šia išraiška jau galima
puikiai realizuoti spyruoklių sistemas.
Bendru atveju ši
formulė naudojama vektorinėje formoje ir 3D erdvėje nagrinėjant kiekvieną mazgą
sistemoje - skaičiuojant prie jo prijungtų kitų mazgų poveikį esamam. Ilgio pokytis x skaičiuojamas kaip
nagrinėjamo mazgo ir prie jo prijungto kito mazgo pozicijų erdvėje vektorius:
x = current_node.position – prev_node.position
Priklausomai nuo erdvės matmenų formulėje naudojama tiek jo kryptis tiek ir modulis. Na, o slopinimo dėmens greitis – tai reliatyvus mazgų greičių pokytis:
v = current_node.velocity – prev_node.velocity
Galų gale tamprumo
jėgų skaičiavimus atliekame kiekvienam, prie nagrinėjamo mazgo prijungtam,
mazgui. Kaip ir minėjau, vienas iš būdų tai padaryti - papildant RigidBody klasės jėgos nustatymo
metodą applyForces() štai taip:
gravity = vec(0, -9.81, 0)
object.forces = vec(0, 0, 0)
object.forces += gravity * object.mass
//
use Hooke's law & apply damping
//
F = -k*|x-length| - b*v
dir
= object.position - prevObject.position
x
= length(dir) - maxSpringLength
hookesForce
= - k * x * normalized(dir)
relativeSpeed
= object.velocity - prevObject.velocity
hookesForce
+= - b * relativeSpeed // apply damping
object.forces += hookesForce
Na štai, pagrindinis ir
svarbiausias metodas papildytas. Belieka tik keletas papildomų darbų – sukurti
virvę sujungiant kelis kūnus viena su kitu bei pakoreguoti piešimą, kad būtų
piešiama virvė sujungta tiesėmis. Bendru atveju virvės kūrimo metodas
pseudokodu atrodytu taip:
prevNode = null
for number of rope nodes do
node
= createNode (parent = prevNode)
addPhysicalBody node
prevNode
= node
Papildomai reikia atkreipti dėmesį į tai, jog jei
visi virvės kūnai judės (nebus fiksuoti vietoje) tai virvė nuo gravitacijos (ar
kitų jėgų) tiesiog nukris, todėl vaizdumo dėlei pirmąjį virvės kūną galima
fiksuoti vietoje. Tai galima atlikti jėgų nustatymo metode - tiesiog fiksuoto kūno neveikti jokia jėga (F = 0). Tokiu atveju virvė gražiai kabos aplinkoje kaip
pavyzdyje.
Mano nurodytame jėgų nustatymo pavyzdyje
mes tamprumo (Huko) jėgą skaičiavome ir pridėjome tik vienam kūnui, nors pagal
teoriją – abu kūnai yra veikiami tokio pat modulio tik priešingų krypčių
tamprumo jėgos. Galbūt sakysite, kad tai nėra visiškai teisingas būdas, tačiau
tai priklauso nuo to, ko jums reikia. Jei tamprumo jėgą pridėsime kiekvienam
kūnui (mazgui), gausime tikrai teisingą būdą, tačiau prikabinus daugiau nei
vieną mazgą virvė labai ištįs dėl prikabintos mazgų masės. Jei mums reikia
fiksuotų vienodų atkarpų tarp mazgų – lieka jėgą nustatyti tik vienam kūnui. Kitas sprendimas būtų mažinti mases arba proporcingai
didinti tamprumo jėgos modulį didinant tamprumo koeficientą k.
Virvė pagal tikrą fizikinį modelį, kai tamprumo jėga veikia abu, spyruokle sujungtus, kūnus |
Virvė su vienodais segmentų ilgiais, kai tamprumo jėga veikia tik vieną kūną |
IV. Tolesnės galimybės
Spyruoklės leidžia realizuoti
įvairius įdomesnius fizikinius mechanizmus. Dar nepakalbėjome apie 3D
geometrijos (pvz. žėlė) bei drabužių simuliaciją, tačiau galbūt jau įsivaizduojate
kaip tai galima būtų atlikti. Idėjos šiems objektams paprastos kaip ir virvei –
tiesiog naudoti spyruokles, tik jų žymiai daugiau. Drabužiai sudaromi iš
eilutėmis/stulpeliais sudėtų kūnų(rigid-body), prie kurių prijungta nemažai
spyruoklių. Veikdamos kartu iš įvairių pusių jos puikiai imituoja drabužio medžiagą.
Kiti spyruoklių taikymo būdai - drabužiai(audinys), minkšti kūnai - žėlė |
Trimačiai minkšti
besideformuojantys (soft bodies) modeliai sudaromi iš daugelio gardele spyruoklėmis
sujungtų kūnų. Dažnai kūnai tiesiog talpinami geometrijos viršūnėse (vertex) ir
sujungiami spyruoklėmis pagal trikampių kraštus. Kadangi reikalaujama, kad
spyruoklės stengtųsi išlaikyti savo ilgį, tai kūnas gali išlaikyti ir savo
formą lengvai svyruodamas ir deformuodamasis, jeigu jį veikia jėgos. Ech,
pagaliau apžvelgėme spyruoklių fizikos pagrindus, dabar bus galima atsikvėpti
ir paeksperimentuoti – tad iki sekančio susitikimo!
Realizuotą projektą su Java Processing galite parsisiųsti iš čia.
Daugiau informacijos:
Realizuotą projektą su Java Processing galite parsisiųsti iš čia.
Daugiau informacijos:
- Ian Millington, Game physics engine development
- Grant Palmer, Physics for game developers
- David Conger, Physics modelling for game developers
Komentarų nėra:
Rašyti komentarą