Gör en simpel fysikmotor i C#.NET men kan inte klura något bra sätt att räkna ut hur mycket av en impuls som skall gå till rotation, resten går till "vanlig" hastighet. Vilka variabler skall man ta hänsyn till? Spontant tror jag du får använda angreppspunkten (eller angreppslinjen om du har ett stelt objekt -- normalfallet) och trixa lite med tröghetsmomentet. Du måste utöver hastighet och position ha alla rotationer och hela rörelsemängdsmomentet sparat för varje objekt. Jag har byggt upp hela fysikmotorn genom att lägga till en feature i taget. Rotation _är_ svårt, och det är inte helt sannolikt att man gör rätt på första försöket. Betänk att du har tre olika rotationer. Det är till exempel avgörande i vilken ordning du applicerar dem. Jag var osäker på impulsmomentet på rotationshastigheten och därför tog jag fram ett annat sätt att lösa det på. Nämligen att räkna ut hastigheten som rotationen bidrar till och låtsas att det är en del av objektets "vanliga" hastighet, och just nu verkar det fungera. Bara en liten, liten fundering från min sida: Jag funderar på om du inte borde wrappa dina anrop till trigonometriska funktioner, utifall att du någon gång i framtiden ska köra en cache på de anropen då de är ganska beräkningsintensiva för live-körning Istället för att anropa Math.Sin så borde du ha ett eget bibliotek, och då anropa t.ex. MyMath.Sin istället. I nuläget gör du i MyMath.Sin bara så att den funktionen anropar vanliga Math.Sin. Jaha, men detta har jag redan provat, och det blev inte snabbare visade mina omfattande tester. Är du säker på att matteprocessorn utför avrundningen snabbare än den beräknar sinus? Hm.. Har den färdiga instruktioner för sinus..? Fast hm.. Den är långsammare verkar det som ändå, även om det inte skiljer något enormt. Hur som haver, jag skulle iaf. wrappa det anropet så det finns möjlighet att tweaka utan att klura ut i efterhand vad som går att wrappa och inte. <b>Har den färdiga instruktioner för sinus..?</b> > Jovisst. Sinus och cosinus är så viktiga för grafik att de finns färdiga.Fysikmotor, rotation
Har någon ett bra sätt att ta reda på vilket håll objekten skall rotera så är det också välkommet.Sv: Fysikmotor, rotation
Sv:Fysikmotor, rotation
När jag skulle lägga till rotation blev det väldigt många frågor som behövde svar samtidigt. En svår grej är att man måste få det balanserat, alltså att jag inte skapar eller tar bort energi.
Vid en kollision så ska jag:
1. Räkna in rotationen som ett bidrag till resultatet. För att göra detta så räknar jag helt enkelt ut vilken hastighet som rotationen har i kollisionspunkten och lägger på detta på den "vanliga" hastigheten.
2.Räkna ut den resulterande rotationen. Det är här the shit hits the fan. För att räkna ut hur stor del av impulsen som ska gå till rotation så kollar jag vinkeln mellan impulsen och masscentrat på de båda polygonerna som kolliderar. Desto större vinkel, desto större del av impulsen går till rotation.
Grejen är att jag hittils "kommit på" allt själv så det är bättre jag får bättre förståelse än att jag hittar någon text där det står exakt hur man gör, eftersom jag kanske inte gjort resten likadant.Sv: Fysikmotor, rotation
Vad jag definitivt kan säga är att du måste ha tröghetsmomentet för att få en korrekt rotation. Det är relaterat till avståndet från medelpunkten. Jag blir lite skeptisk när du säger att du "kan ha gjort det på ett annat sätt". Det ska inte spela någon roll om du verkligen baserar det på korrekta fysiska lagar. Principen är:
1. Ta fram punkten eller linjen som kraften verkar på. Det verkar du ha fixat.
2. Ta fram tröghetsmomentet utifrån den punkten.
3. Ta fram den momentana kraften och ur den, det momentana momentet. Detta översätter du nog då till en impuls och ett impulsmoment (är det verkligen rätt ord?), där du låter impulsen verka på rörelsemängd, och impulsmomentet på rotationshastigheten.
Vad du får i det momentana fallet är ju
F = m a
och
L = I d_omega/d_tSv:Fysikmotor, rotation
Mitt stora problem hittils var att ta reda på vilken resulterande rotation som, i detta fallet, polygonen skulle erhålla. Såhär löste jag det iallafall:
public static float ComputeRotationOsuus(PointF Impulse, PointF PointOfCollision, PointF CenterOfMass)
{
float collisionToCenterOfMassAngle = Angle(PointOfCollision, CenterOfMass);
float directionOfImpulse = Angle(Impulse);
return -(float)Math.Sin(directionOfImpulse - collisionToCenterOfMassAngle);
}
Väldigt irriterande att så lite kod var det som gav "önskat" resultat. Angle är bara en funktion som ger vinkeln mellan två punkter. Denna funktionen ger bara hur stor del av impulsen som ska gå till rotation, och även vilket håll rotationen skall vara riktad åt.
Det jag nu arbetar på är att få alla impulser att få exakt rätt storlek. Det återstår att se om det fungerar med min metod.
Sv: Fysikmotor, rotation
Sv: Fysikmotor, rotation
Om/när det här sedan används ännu mer så kan man tänka sig att en stor mängd saker ska beräknas, och då kommer Math.Sin relativt sett vara rätt tungkört. Då kan du väldigt enkelt i din MyMath.Sin-funktion göra om så att du avrundar indatan och sedan plockar ut ett cachat värde ur en färdig array. Noggranheten sjunker lite, men å andra sidan, i t.ex. ett spel så är det inget som kommer att märkas. Däremot blir allting mycket snabbare när man kör det hela.
(Vanlig sinus/cosinus etc. är väldigt beräkningsintensiva funktioner, så att cacha och göra ungefärliga uträkningar är det enda vettiga i t.ex. 3d-spel för att de ska hänga med ordentligt..)Sv:Fysikmotor, rotation
Sv:Fysikmotor, rotation
Sv: Fysikmotor, rotation
(Att göra avrundning för att göra lookup i array är snabbt gjort, bara en bitshiftning + plocka ur värdet i teorin, iaf. sålänge värdena ligger mellan 0 och 2 pi)Sv:Fysikmotor, rotation
Jovisst. Sinus och cosinus är så viktiga för grafik att de finns färdiga.Sv: Fysikmotor, rotation
Kom fram till det när jag skrev föregående post, men om jag förstod rätt enligt vad jag hittade så är det relativt långsamma instruktioner det handlar om