Gelésimulering 22 mars 2008
2
Sammanfattning Vi har i kursen Modelleringsprojekt TNM085 valt att simulera ett geléobjekt i form av en kub. Denna består av masspunkter som är sammankopplade med tre olika typer av fjädrar med olika parametrar. Målet var att få simuleringen så realistisk som möjligt, detta genom att experimentellt ta fram värden på parametrarna till fjädrar och friktion. En kollisionsmodell har implementerats för att visa geléobjektet på ett mer realistiskt sätt. Om man är vill göra en simulering som visar de grundläggande egenskaperna hos gelé är fjädermodellen ett bra alternativ. Simuleringen klarar att köras i realtid med en begränsning med ca 260 masspunkter vilket blir ca 2500 fjädrar för geléobjektet.
4
Innehåll 1 Inledning 7 1.1 Bakgrund............................................... 7 1.2 Syfte.................................................. 7 2 Metod 9 2.1 Förstudie............................................... 9 2.2 Matematisk modell.......................................... 9 2.3 Eulers stegmetod........................................... 10 2.4 Fysikaliska formler.......................................... 10 2.5 Implementation............................................ 11 2.5.1 2D simulering........................................ 11 2.5.2 3D simulering........................................ 11 2.6 Flöde för fysikaliska beräkningar................................... 13 3 Resultat 15 4 Slutsats och diskussion 17 A Manual 19 5
6
Kapitel 1 Inledning 1.1 Bakgrund Detta arbete är ett resultat av projektet i kursen Modelleringsprojekt TNM085, vårterminen 2008. Denna kurs bygger vidare på kursen Modellbygge och Simulering TNG022 där man lär sig att skapa en modell av ett fysikaliskt system. För en civilingenjör i medieteknik är det viktigt att kunna implementera och åskådliggöra fysikaliska modeller i en grafisk representation. 1.2 Syfte Syftet med projektet är att simulera ett fysikaliskt system i form av ett geléobjekt samt visa det grafiskt. Detta ska ske i realtid på en modern dator. Projektet kommer även ge oss kunskaper om hur de teoretiska modellerna implementeras i en grafisk simulering. 7
8
Kapitel 2 Metod 2.1 Förstudie Det vanligaste sättet att simulera gelé är att använda sig av masspunkter som är sammankopplade med flera fjädrar [1][2][3]. Genom att justera fjädrarnas parametrar kan man få önskade egenskaper hos geléobjektet. För att motverka att fjädersystemet förlorar volym vid deformation tillämpas en gaslag som ser till att systemet har en konstant volym. För att det ska bli mer intressant att se på kommer även en kollisionshantering att implementeras. Vi valde att göra ett geléobjekt i form av en kub för att begränsa projektets storlek. Masspunkterna kan då placeras likt hörnpunkterna i många små inre kuber. Detta gör det enklare att konstruera fjäderstrukturen. Det finns olika alternativ att binda ihop masspunkterna med fjädrar. Enklast är att ta de närmaste masspunkterna (som figur 2.1(a) nedan illustrerar) och koppla ihop dem med fjädrar som härmed benämns sidofjädrar. Detta kommer dock ge en svag struktur som lätt kollapsar. För att motverka detta kan det dras fjädrar mellan diagonalerna (se figur 2.1(b)) och rymddiagonalerna (se figur 2.1(c)). (a) sidofjädrar (b) diagonalfjädrar (c) rymddiagonalfjädrar Figur 2.1: De olika typer av fjädrar vi implementerar Det är svårt att uppskatta bra värden på fjäder- och dämningskonstanter därför kommer dessa att tas fram experimentellt. Densiteten uppskattats till att överensstämma med densiteten hos riktigt gelé. Ett enkelt test av systemet gjordes genom att bygga fjädermodellen i 3D Studio Max och detta test bekräftade att modellen var tillräckligt realistisk. Vid implementeringen användes programmeringsspråket C# med ramverket XNA [4]. För att få hjälp med vissa funktioner i programmeringsspråket användes Riemers XNA Tutorials [5] 2.2 Matematisk modell En bindingsgraf (se figur 2.2(b)) ställdes upp för en masspunkt med en ansluten fjäder (se figur 2.2(a)). Figuren illustrerar de krafter som påverkar en masspunkt som är på väg bort ifrån den masspunkt den är kopplad till. F Dämpning har motsatt riktning till hastigheten v. Från bindningsgrafen kunde vi sedan härleda en differentialekvation. a är accelerationen hos en masspunkt, m massan, x positionen och v hastigheten. 9
(a) Krafterna som påverkar en masspunkt (b) Bondgrafen Figur 2.2: Krafter på masspunkt med tillhörande bindningsgraf 2.3 Eulers stegmetod x 2 t 2 = v = a = 1 m ( F Hook F Dämpning F Gravitation ) (2.1) Eulers metod används för att numeriskt lösa differentialekvationen (2.1). Metoden använder första ordningens taylorutveckling för att approximera lösningen till differentialekvationer. Standardformen på Eulers stegmetod ser ut som följande i det diskreta fallet: y k+1 = y k + f(t k, y k )h (2.2) h är steglängden, y k+1 är värdet i nästa tidspunkt, y k är det föregående värdet och f(t k, y k ) är derivatan till y k. Initialvärden på y k och f(t k, y k ) behövs för att kunna lösa differentialekvationen. Man använder alltså derivatans riktning i tidpunkten k och rör sig sedan i denna riktning under tiden h. Denna metod körs iterativt. 2.4 Fysikaliska formler För att beräkna kraften av fjädern användes Hookes lag (2.3) där k Hook är fjäderkonstanten och x 0 viloläget för fjädern. F Hook = k Hook (x x 0 ) (2.3) Denna måste utökas till tre dimensioner med vektorer för att få rätt riktning på kraften, vilket ger oss formeln (2.4). L är vektorn från masspunkt B till A. F Hook = k Hook ( L L x 0 ) L (2.4) Eftersom fjädrarna inte oscillerar i all oändlighet måste man ta hänsyn till dämpning, k Dämpning är dämpningskonstanten. F Dämpning = k Dämpning v (2.5) Även denna ska gälla för tre dimensioner, och skall därför också utökas, L är samma som tidigare, v A och v b är hastigheten hos masspunkten A respektive masspunkt B. F a = k ( v A v B ) L L D mpning Dämpning L L (2.6) 10
För att simulera friktion användes friktionsformeln, N är normalkraften och µ är friktionskonstanten : F F riktion = µn (2.7) Gravitation, m är massan hos en masspunkt och g har valts till 9,82: F Gravitation = mg (2.8) 2.5 Implementation 2.5.1 2D simulering För att minska komplexiteten och få ett snabbare resultat gjordes inledande simulering av gelén i endast två dimensioner. Detta bekräftade att komponenter som Eulerintegration, fjäderberäkningar och visualiseringen fungerade. Klass Particle Denna klass representerar en masspunkt med parametrarna: position, vikt, hastighet, acceleration och resulterande kraft (total kraft som påverkar masspunkten). Här beräknas accelerationen med hjälp av ekvation (2.1), samt hastigheten och den nya positionen med ekvationen (2.2) i klassen Euler. Gravitationen (2.8) läggs också till som ursprungligt värde i den resulterande kraften Klass Spring Denna klass representerar en fjäder med parametrarna: längd (fjäderns längd i viloläge), fjäderkonstant och dämpningskonstant. Här beräknas fjäderkraften givet avståndet och relativa hastigheten, med hjälp av (2.4) och (2.6). Klass Euler Denna klass utför numerisk integrering då derivata och tidigare värde är givna. Klass BaseCube2D Denna klass skapar alla masspunkter och binder ihop dem med fjädrar. Härifrån anropas också metoderna i klasserna Spring och Particle för att beräkna krafter och nya positioner. Klass PolygonCube2D Denna klass ritar ut polygoner med masspunkter som referens. Struktur Vid körning skapas först ett BaseCube2D objekt som lägger in masspunkter i en matris av önskad storlek. Utifrån denna matris skapas sedan de olika fjädrarna som sammankopplar masspunkterna med varandra. Dessa lagras i en matris där varje rad innehåller två masspunkter som är sammankopplade med en fjäder. Detta behöver bara köras en gång och är grunden till simuleringen. För varje bildruta beräknas fjäderkraften för alla fjädrar. Dessa krafter adderas sedan till respektive masspunkts resulterande kraft. Den resulterande kraften hos en masspunkt används för att beräkna dess acceleration. Då accelerationen har beräknats kan den nya hastigheten tas fram med hjälp av Eulerintegration. På samma sätt kan den nya positionen bestämmas utifrån hastigheten. För att kompensera avsaknaden av kollisionshantering fixerades vissa masspunkter så att den inte faller fritt. 2.5.2 3D simulering I den tredimensionella simuleringen utökades befintliga klasser. Klasserna Particle, Spring och Euler förblir dock oförändrade. Klass BaseCube3D Precis som BaseCube2D skapar denna klass alla masspunkter och binder ihop dem med fjädrar. Skillnaden är att masspunkterna lagras i en tredimensionell matris, vilket ger en direkt motsvarighet till positionerna i kuben, samt att fjäderstrukturen har utökats med rymddiagonala fjädrar. Här ligger även kollisionshanteringen och friktionsberäkningarna. 11
Klass PolygonCube3D Precis som PolygonCube2D ritar denna ut polygonerna utifrån masspunkterna. Skillnaden är att den nu plockar ut de yttre masspunkterna och ritar upp var och en av kubens sex sidor för sig. För att ljussättningen ska bli rätt beräknas också normalen för varje vertex (masspunkt), varje gång bilden uppdateras. Enkel kollisionshantering Som en inledande, förenklad version av kollisionshantering bestämdes en höjd på y-axeln som masspunkterna i kuben hindrades från att komma under. För att göra detta flyttades masspunkterna upp till den givna höjden, samt nollställa den resulterande kraften i y-led. Detta görs innan acceleration, hastighet och positionen uppdateras. Avancerad kollisionshantering I varje tidsteg kontrolleras varje masspunkt i geléobjekt om den befinner sig inuti ett annat objekt. Detta görs genom att för varje polygon i det objektet beräknas skalärprodukten mellan polygonens normal (N) och en vektor (v) från en punkt på polygonen till den aktuella masspunkten (se figur 2.3(a)). Det ger avståndet h mellan polygonen och masspunkten. Om det är negativt ligger masspunkten på baksidan av polygonen (se figur 2.3(b)). Om alla avstånd för en masspunkt är negativa befinner den sig i objektet och då måste åtgärder vidtas. De punkter som upptäcks vara i objektet flyttas ut ur objektet (se figur 2.3(c)). Hastighet och acceleration måste också uppdateras. För att veta vart punkten skall flyttas kontrolleras vilket avstånd som är minst, då vet man vilken polygon som är närmast. Masspunkten flyttas sedan det avståndet enligt den närmaste polygonens normalriktning. För masspunkten räknas normalkraften genom att beräkna skalärprodukten mellan polygonens normal och resulterande kraft på masspunkten. Det multipliceras sedan med normalen för att få rätt riktning på kraften. Normalkraften adderas sedan från masspunkten resulterande kraft. Samma princip används för att beräkna en ny hastighet, men istället för resulterande kraft används masspunktens hastighet. Allt detta görs för att masspunkten inte skall fortsätta in i objektet. (a) Före kollision (b) Upptäckt kollision (c) Justerad Figur 2.3: Kollisionshanteringen Friktion Friktionen beräknas bara för de masspunkter som fångas upp av kollisionshanteraren. Detta beräknades genom att använda friktionsformeln (2.7) där normalkraften är lika stor som masspunktens resulterande kraft i y-led (innan denna nollställs), men vänd åt andra hållet. Precis som i riktig friktion har olika friktionskonstanter implementerats för stillastående och för rörelse. Om masspunkten är stillastående jämförs längden av kraftvektorn, efter att den nollställts i y-led, med längden av friktionskraftens vektor. Om friktionskraften är störst nollställs hela kraften på masspunkten, så att den inte rör på sig. Om friktionskraften är minst kommer masspunken att vara i rörelse och en ny friktionskraft beräknas, med lägre friktionskonstant. Friktionskraften vid rörelse verkar som en konstant kraft, motsatt rörelseriktningen. Grafik Vi skapar först en abstrakt version av vår gelékub, men för att kunna visualisera den måste vi även skapa en grafisk representation av den. För detta skrev vi en funktion som efter givna data skapar en polygon kub. Varje sida av kuben är uppdelad i ett antal mindre polygoner, där storleken bestäms av partikelavståndet. För enkelhetens skull 12
sätter vi samma färg på alla polygoner. 2.6 Flöde för fysikaliska beräkningar För varje blidruta För varje fjäder i fjädermatrisen Beräkna fjäderkraften Beräkna dämpningskraften Addera resulterande kraft till masspartiklarna För varje masspunkt (I 3D fallet görs även detta) Om masspunkt kolliderar med ytan Flytta ut masspunkt och projicera resulterande kraft, hastighet och acceleration i ytnormalens riktning Beräkna friktion och uppdatera den resulterande kraften Addera gravitationen till resulterande kraft Beräkna acceleration Beräkna hastighet med hjälp av eulerintegration Beräkna position med hjälp av eulerintegration Uppdatera position Texten nedan är en sammanfattning av de fysikaliska beräkningar som utförs när programmet körs. - - 13
14
Kapitel 3 Resultat De fjäderkonstanter och dämpningskonstanter som ger en simulering som är mest verklighetstrogen är listade i tabellen nedan (Tabell 3.1). Tabell 3.1: Fjäder- och dämpningskonstanter Sidofjäder Diagonalfjäder Rymddiagonalfjäder Fjäderkonstant 400N 420N 440N Dämpningskonstant 1,5 1,5 1,5 Densiteten har vi valt till: 1000kg/m 3 Storleken har vi valt till: 5x5x5x0,02 (Bredd x Höjd x Tjockleck x Partikelavstånd) Vilket ger oss en massa på 1kg. Varje masspunkt väger då 8g. För Eulersteget använder vi : h = 0.008 Resultatet i två dimensioner (se figur 3.1). Gelékuben utsätts för krafter på de översta masspunkterna (figur 3.1(a)) och den följande bilden (figur 3.1(b)) visar hur kubens fjädrar blir ihoptryckta. Fjädrarna vill gå tillbaka till sitt viloläge och därför försöker kuben återgå till sin orginalform (figur 3.1(e)). De nedersta masspunkterna är fixerade för att inte undvika fall i oändlighet. Observera att strecken på gelékuben motsvarar polygonernas linjer och inte fjädrarna. (a) (b) (c) (d) (e) (f) Figur 3.1: 2D-simulering 15
Resultatet i tre dimensioner (se figur 3.2). Gelékuben flyttas upp ovanför marknivån (y=0) och släpps sedan ner (figur 3.2(a)). Vid kollision med marknivån trycks fjädrarna ihop (figur 3.2(c)) vilket resulterat i att kuben dras samman för att sedan försöka återta sin orginalform (figur 3.2(f)). (a) (b) (c) (d) (e) (f) Figur 3.2: 3D-simulering Begränsningen för vår simulering är ca 260 masspunkter, vilket blir ca 2500 fjädrar. Detta kommer resultera i ca 600.000 fjäderberäkningar/sek. Även kollision och grafikberäkningarna som utförs tar en del prestanda. Den dator vi har utfört simuleringen på har följande specifikationer: Intel Core 2 Duo 2.0Ghz 2048 Mb ram ATI X1800 mobility 256Mb Gelékuben kan kollapsa om den utsätts för stora krafter. Anledningen till att detta sker är att fjädern trycks ihop så mycket att startpunkten passerar slutpunkten och trycks ut åt fel håll då den söker sitt viloläge. Det leder till att kuben bli deformerad. 16
Kapitel 4 Slutsats och diskussion Strukturen på vår modell består av sido-, diagonal- och rymddiagonalfjädrar. Detta ger en acceptabel simulering av gelé i realtid, så länge inga stora krafter påverkar geléobjektet. För att undvika detta utförde vi test med fyra stycken rymddiagonalfjädrar på hela kuben. Detta ökade stabiliteten något men medförde också ett orealistiskt beteende hos kuben. Därför valde vi att inte använda det. Simuleringen kan köras med endast sido- samt diagonalfjädrar dock ger det bättre stabilitet med rymdiagonalfjädrar. Gaslagen implementerades inte. Detta för att det gav ett tillräckligt bra resultat med rymddiagonalfjädrarna. De fjäder- och dämpningskonstanter som används ger en acceptabel dallrande konsistens samt en stabil struktur som inte kollapsar. Högre fjäderkonstanterna ger en fastare struktur och högre dämpningskonstant gör att dallringarna minskar. Eulers stegmetod är beroende av en liten steglängd för att simuleringen skall vara stabil. Om en större kraft verkar på en masspunkt och steglängden är för stor kommer detta leda till att krafterna blir okontrollerbara. Inträffar det kommer objektet att exploderar. För att undvika det har vi valt att använda en liten steglängd, detta ger dock en långsam simulering. Detta löstes genom att uppdatera simuleringen flera gånger för varje bild som visas. Det som sätter begränsningen på hur många uppdateringar man kan köra är datorns prestanda. Vår kollisionsmodell fungerar för konvexa och statiska objekt. Kollisionsmodellen beräknar endast för geléobjektets masspunkter och inte polygoner, vilket kan leda till att en av geléobjektets polygoner kan hamna innanför ett statiskt objekt. Detta inträffar sällan då masspunktsavståndet är relativt litet och är därför inget stort problem. Friktionskonstanterna som används har även den tagits fram via experiment mot ett underlag som vi definierade som plast. Fjädermodellen som vi har använt oss av kan tillämpas på andra mjuka objekt. T.ex. om vi ändrar storleken kan vi simulera objekt som tyg och rep dock är vår simulering inte anpassad till dessa. Om kursen haft en större omfattning skulle vi kunnat utöka vår modell. Bl.a. Kollisionsmodell mellan mjuka kroppar Implementering av gaslag Optimering av kod för bättre prestanda Snyggare grafisk representation 17
Referenslista [1] Paul Mecklenburg och Christian Miller (2004) Jello Simulation [www] http://www.paulmecklenburg.org/school/eecs466/simulati 20 januari 2008 [2] Jernej Barbic Simulating a Jello Cube [www] http://people.csail.mit.edu/barbic/prog3.html 20 januari 2008 [3] Glenn Fiedler (2006) Spring Physics [www] http://www.gaffer.org/game-physics/spring-physics/ 20 januari 2008 [4] Microsoft Corporation (2007) XNA [www] http://xna.com/ 20 januari 2008 [5] Riemer Grootjans (2007) Riemers XNA tutorials [www] http://www.riemers.net/index.php 20 januari 2008 18
Bilaga A Manual För att köra simuleringen måste följande program vara installerade på datorn: Microsoft.NET Framework 3.5 http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en Microsoft XNA Framework Redistributable 2.0 http://www.microsoft.com/downloads/details.aspx?familyid=15fb9169-4a25-4dca-bf40-9c497568f102&displaylang=en DirectX End-User Runtime Web Installer http://www.microsoft.com/downloads/details.aspx?familyid=2da43d38-db71-4c1b-bc6a-9b6652cd92a3&displaylang=en Simuleringen startas sedan genom genvägen jello.exe. Figur A.1: Skärmdump Kontrollpanelen längst upp till höger tillåter en att experimentera med geléobjektets struktur. Modifiering av fjäderdata kan göras genom att dra i reglagen (A1) där det översta reglaget på varje fjädertyp representerar fjäderkonstanten och den undre dämpningskonstanten. 19
Vikten (A2) kan även den ändras och detta gäller vikten för varje enskild masspunkt. Den totala vikten för hela geléobjekten blir då antalet masspunkter multiplicerat med vikten i kontrollpanelen. Detta kräver att man trycker på resetknappen (A4) för att ändringen ska ha effekt. Storleken på gelékuben kan justeras om man väljer värden på bredd, höjd och tjocklek (A3) genom att trycka plus för att öka med ett steg, minus för att minska. Värdet anger antalet masspunkter i respektive dimension. Även här måste resetknappen (A4) användas. Information om hur många masspunkter, fjädrar av de olika typerna samt totala antalet fjädrar listas i (A5). Kontroller för att styra kameran är följande (håll in shift plus angiven knapp för att öka hastigheten på rörelserna): A Rörelse i sidled, vänster D Rörelse i sidled, höger W Rörelse framåt S Rörelse bakåt R Rörelse uppåt F Rörelse nedåt Pil vänster Rotera vänster Pil höger Rotera höger Pil upp Titta upp Pil ner Titta ner Kontroller för att påverka kuben (i förhållande till kameran): Ctrl + A Putta vänster Ctrl + D Putta höger Ctrl + W Putta framåt Ctrl + S Putta bakåt Inställning av grafisk representation: 1 visa sidofjädrar 2 visa diagonalfjädrar 3 visa rymddiagonala fjädrar 4 visa polygonrepresentationen För att avsluta programmet tryck på krysset uppe i högra hörnet eller på tangenten esc. Vi har testat det på dator med följande specifikationer, det går även att köra på en sämre dator: Windows XP Intel Pentium 4 3.6 GHz 1024 MB RAM-minne nvidia GeForce 6800 GT 256 Mb 20