Fysik: Biljardbordet
Labbmaterialet finns här:
common.zip (Alla hjälpfiler.)
2023-versionen:
lab3x.tar.gz (nya C++-versionen, uppdaterad)
I denna laboration skall vi arbeta med lite grundläggande klassisk fysik i en spelsituation. Miljön är ett biljardbord, där vi ska få bollarna att interagera på ett så realistiskt sätt som möjligt (inom rimliga gränser). Situationen tillåter ett antal bekväma förenklingar. Till exempel blir kollisionsdetektering mycket lätt.
Viktiga koncept: Kollissionshantering i praktiken. Impulser. Rörelsemoment.
Laborationsskalet
Labbskalet består av huvudprogrammet "lab3.c" och ett antal hjälpfiler. De flesta känner du igen från tidigare labbar.
Laborationen är utvecklad av Ingemar Ragnemalm för att ersätta en äldre, liknande labb som byggde på ett betydligt mer komplicerat ramverk, vilket var bra på sitt sätt men för komplicerat för en labb och gjorde det mycket svårt för kursdeltagare som ville göra labben på sin egen maskin. Labben är nu också mer uttalat fokuserad på kapitel 8 i boken (Rigid body animation).
Ladda ner labbskalet med länk ovan.
Titta igenom lab3.c/cpp. Du kommer framför allt att arbeta i funktionen updateWorld(). I denna funktion är en tillståndsuppdatering (enligt boken) given, samt enkla vallkollisioner, men mellan dessa skall du införa en mängd funktionalitet.
Uppgift 0: Kom igång
Som vanligt är första problemet att alls kunna kompilera och köra. Packa upp filerna och kompilera med make.
Uppgift 1: Enkel rotation
Bollarna rör sig, men de glider bara omkring. Hela animationen blir mycket trevligare om bollarna får en rotation som följer rörelsen över bordet. Om vi för ögonblicket glömmer bort att det är en fråga om friktion så kan vi fuska till detta ganska snyggt bara genom att sätta en rotation som stämmer med rörelsen. Dvs rotationen påverkar inte övriga rörelsen. Det innebär också att den relativt svårbegripliga och svårhanterade tröghetsmatrisen kan förenklas extremt och utgör egentligen bara en skalning.
Implementera detta i funktionen updateWorld().
Funktionen cross eller ArbRotate (i VectorUtils3.c/VectorUtils4.h) kan vara användbara i denna uppgift.
Uppgift 2: Friktionsfria kollisioner mellan bollar
Bollarna kolliderar ju inte, och det är nästa steg. Det går att göra grovt förenklade kollisioner, som vi beskrev i grundkursen, men nu gör vi det lite mer generellt. Vi arbetar därför inte bara med bollarnas hastighet utan också med massa och rörelsemoment.
Dock kan vi göra flera stora förenklingar jämfört med beskrivningen i boken. I slutet avsnittet om kollisionsrespons (8.4, sid 139 i b3-versionen men sidnummer kan ändras) ser vi en ganska komplicerad formel. Dock kan den förenklas betydligt av det faktum att vi bara använder sfärer. Vi tillåter oss att utnyttja detta.
Fråga:
Vad blir den förenklade formeln?
Vi börjar med att detektera kollision. Sedan skall du se till att de stöter ifrån varann.
Fråga:
Vad behöver du göra för att inte bollarna skall fastna i varandra?
Implementera impulsformeln (med hjälp av VectorUtils3) och gör nedanstående experiment för att testa din implementation.
Testfall 1: VD-leksak/Newtons vagga
Ställ in labbskalet på att animera 4 bollar (kNumBalls) samt elasticitet 1. Dessa är placerade på ett sätt som motsvarar Newtons Vagga, ni vet de där sakerna där ett antal stålkulor hänger i ett snöre. Detta är ett trevligt testfall där man vet precis vad resultatet bör bli.
Testfall 2: En tung boll och många lätta
Ställ in labbskalet så att inte alla rör sig på linje längre. Sätt (i init()) en av dem till avvikande massa, lämpligtvis större. Testa, klarar din modell även detta fall?
Testfall 3: Variera elasticiteten
Ändra elasticitet till 0.5 eller 0. Kolliderar bollarna som du väntat dig?
När din implementation klarar dessa tre fall så kan du med gott samvete anta att det fungerar korrekt.
Fråga:
Vilket av testfallen var svårast att uppfylla, och varför?
Uppgift 3: Friktion mot bordet
Ändra till alla bollar igen.
Vi vill klara ett fall till, att skapa någorlunda realistisk friktion mot bordet. Utan realistisk friktion mot bollarna blir detta inte så perfekt, eftersom bollarna inte utbyter rotation, men vi kan i alla fall få en boll att anpassa sin rotation efter sin rörelse med en fysikaliskt betingad modell.
I uppgift 2 kunde vi helt bortse från tröghetsmatrisen, men det kan vi inte nu. Vi måste ansätta en tröghetsmatris som är tillräckligt bra för att representera en boll.En möjlig approximation är så här: Sex punktmassor placerade på ytan av klotet, var och en med massan m/12, samt en större punktmassa i centrum med massa m/2. Denna skall användas för att beräkna rotationshastigheten omega från rörelsemängdsmomentet L.
Det finns också tröghetsmoment givet i supplementet, vilket är mer exakt. Hur kan vi använda det?
Frågor:
Vad blir tröghetsmatrisen för denna modell?
Hur kan denna tröghetsmatris på enklast möjliga sätt användas för att beräkna rotationshastigheten omega från rörelsemängdsmomentet L?
För att nu beräkna en kraft måste vi beräkna hastighetsskillnaden i bollens kontaktpunkt med underlaget. Hur finner vi denna hastighetsskillnad?
När vi väl har den så skall en kraft beräknas. En friktionskonstant kan ansättas efter behag. Vi kräver inte 100% realistisk friktion. Vad vi kräver är att det syns att bollarnas rotationer ändras när bollen glider över ytan så den efter hand övergår till rullning och att detta baseras på en pålagd kraft.
Därmed är vi klara med laborationen! Redovisa resultatet för assistenten. De frågor som finns ovan skall vara besvarade innan redovisning, vilket jag hoppas föll sig naturligt under labbens gång.
Extrauppgift 1: Kollisioner mellan bollar med friktion
Om du är riktigt sugen på att göra ett bra biljardbord så är nästa steg att införa friktion i kollisionen mellan bollar. Detta är dock en ren extrauppgift som vi inte ens tagit fram något facit på.
Extrauppgift 2: Biljardkö mm spelfunktioner
Och om du är sugen på att jobba vidare med vårt fina biljardbord så är en annan fortsättning att införa en ordentlig kö och trevlig styrning och kontroll av slagstyrkan mm. så det närmar sig ett riktigt spel. Då börjar vi förstås närma oss någon sorts projekt. Jag nämner det bara som en ren frestelse. :-)