News:

No significant change

Main Menu

Matematiktråden!

Started by Lupson, November 10, 2002, 16:08:11

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Lupson

Här kan jag fortsätta med förevisningen av mina katastrofala matematikkunskaper...
/Lupson
Mvh Lupson - kortklippt.

"Kustartilleriet fördröjer fienden i kustbandet till militär hjälp kan anlända".
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Core i5 E3570K - Fractal Design Define Mini - Sapphire R290 Tri-X

Lupson

#1
Får tacka alla så mycket för hjälpen. Nu fungerar höjdfinnaren perfekt! Inga "hopp" i skarvarna etc. Kanske inte så intressant men lösningen blev enl. följande.

float GTH3(float x, float z, BYTE pHeightMap[]){
   
   int helX, helZ = 0;   // Snap-to-grid values
   float a, b, c, d, ret, vsum = 0;
   Vector3 p1, p2 ,p3, p4;

   for(int e = 0;e<x;e+=STEP_SIZE)
      helX = e;
   
   for(int f = 0;f<z;f+=STEP_SIZE)
      helZ = f;
   
   float start_y = Height(pHeightMap, helX,helZ);                        // bottom left, "anchorpoint"
   float end_y_1 = Height(pHeightMap, helX,helZ + STEP_SIZE);               // top left
   float end_y_2 = Height(pHeightMap, helX + STEP_SIZE, helZ);               // bottom right
   float end_y_3 = Height(pHeightMap, helX + STEP_SIZE, helZ + STEP_SIZE);      // top right

   p1.x = helX;
   p1.y = start_y;
   p1.z = helZ;
   p2.x = helX;
   p2.y = end_y_1;
   p2.z = helZ+STEP_SIZE;
   p3.x = helX+STEP_SIZE;
   p3.y = end_y_2;
   p3.z = helZ;
   p4.x = helX+STEP_SIZE;
   p4.y = end_y_3;
   p4.z = helZ+STEP_SIZE;
   
   vsum += p1.CalcAngle(p1, p2, x, z); /* Lägger ihop de tre vinklarna */
   vsum += p1.CalcAngle(p1, p3, x, z);
   vsum += p1.CalcAngle(p2, p3, x, z);
         
   if(vsum > 6.284f || vsum < 6.283f){ /* Ifall vinkelsumman avvike från 2 Pi */
      p1.x = p4.x;
      p1.y = p4.y;
      p1.z = p4.z;
   }
         
   a = p1.y*(p2.z-p3.z)+p2.y*(p3.z-p1.z)+p3.y*(p1.z-p2.z);
   b = p1.z*(p2.x-p3.x)+p2.z*(p3.x-p1.x)+p3.z*(p1.x-p2.x);
   c = p1.x*(p2.y-p3.y)+p2.x*(p3.y-p1.y)+p3.x*(p1.y-p2.y);
   d = -p1.x*(p2.y*p3.z-p3.y*p2.z)-p2.x*(p3.y*p1.z-p1.y*p3.z)-p3.x*(p1.y*p2.z-p2.y*p1.z);
   ret = -(a*x+c*z+d)/b;
   return ret;
}

där CalcAngle som kollar beräknar en godtycklig vinkel i en godtycklig triangel ser ut:
float Vector3::CalcAngle(Vector3 vp1, Vector3 vp2, float x, float z){

   float a, b, c, cosangle;
   a = (float) sqrt(((vp1.x-vp2.x) * (vp1.x-vp2.x)) + ((vp1.z-vp2.z) * (vp1.z-vp2.z)));
   b = (float) sqrt(((vp1.x - x) * (vp1.x - x)) + ((vp1.z - z) * (vp1.z - z)));
   c = (float) sqrt(((vp2.x - x) * (vp2.x - x)) + ((vp2.z - z) * (vp2.z - z)));

   cosangle = -( ((a*a) - (b*b) - (c*c))/(2*b*c));
   return acos(cosangle);
}

Om någon ser några felaktigheter eller möjliga förbättringar får ni gärna meddela det. :)

Nästa post == nästa problem!
Mvh Lupson - kortklippt.

"Kustartilleriet fördröjer fienden i kustbandet till militär hjälp kan anlända".
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Core i5 E3570K - Fractal Design Define Mini - Sapphire R290 Tri-X

Lupson

#2
Nu till nästa tankenöt - att få mina stridsvagnar att ligga jämnt och fint mot terrängen!

Dels vill jag att dom ska ligga jämnt mot den triangel den ligger mot, men jag vill också att ifall objektet ligger över flera trianglar skall positioneras så att det ser verkligt ut, dvs att stridsvagnen även vid backkrön renderas korrekt, dvs att de främre banden är i luften när nästan halva vagnen är över krönet. Vi utgår från att tyngdpunkten ligger mitt i fordonet. Knivigt.

Min tanke är att ta stridsvagnens fyra yttre bandhörn och plocka höjden för dessa fyra punkter. Sedan tar jag dessa 4 punkter (har xyz) och bildar ett plan av dem. Nu är problemet hur jag matematiskt kommer från dessa fyra punkter till de transformeringar som skall göras i OpenGL. OpenGL är så snällt att man inte behöver beräkna matrisomvandlingar själv (ifall man inte vill) utan man använder en funktion:

glRotatef( [grader att rotera] ,0,1,0);

Där ettan är vilken axel man roterar runt. Vill jag rotera kring x-axeln istället flyttar jag ettan en parameter inåt.

Någon som har några bra tips på hur jag kan gå tillväga här? Funderar på om man kanske skulle försöka med att definiera "planet" i en matris för att sedan ta reda på skillnaden mot "världen" (som inte är roterad alls) - sedan tar man och motroterar världen lika mycket som skiljer.
(I opengl renderar man alltid utifrån ett oroterat origo. Vill man att det ska se ut som att ett objekt roteras eller flyttas, då flyttar man världen och roterar den istället för tvärtom...) Men matrisberäkningar fattar jag lite för lite av. Känns förvisso lite B att knappt försöka själv men någon kanske tycker det är lite roligt med sånt här.. :)

Tacksam på förhand!
/Lupson
Mvh Lupson - kortklippt.

"Kustartilleriet fördröjer fienden i kustbandet till militär hjälp kan anlända".
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Core i5 E3570K - Fractal Design Define Mini - Sapphire R290 Tri-X

griffin

Hmmm... intressant!

*Funderar*... se om jag kommer på nån bra algoritm...

Griffin
snappahead

AndersO

Vet inte riktigt hur man ska göra.. Men borde väl bli nåt åt de här hållet:

1. Räkna ut planet/normalen som objektet står på
2. Räkna ut vinklar mellan objektets "upp vektor" och normal vektorn (borde väl bli två, roll & pitch)
3. Rotera objektet

De var iaf lätt att skriva. :)


ââ,¬Å"I will make weapons from your booones!!ââ,¬Â

griffin

Är det verkligen så enkelt?

Jag var inne på att bedöma om fordonet stod på en konvex eller konkav yta och räkna vidare på det, men har man osis kan ju fordonet stå på massor med polygoner och då blir det lite mer att ta hänsyn till....

Om man får anta att fordonet kan stå på t.ex. max en konkav/konvex skarv så blir det lite enklare... tror jag. Då handlar det om att bedöma om ytan det står på är konvex eller konkav. Det senare ger ju att man bara plockar fordonets markpunkter (hjul) där de intersectar markpolygonerna och får fram planet fordonet står på. I det första fallet handar det om att ta fram var fordonets centrumpunkt (för gravitation) befinner sig och projicera ned den på markpolygonen. Träffad triangel ger lutningen på fordonet.

Men detta är ju enkla fall. Det blir värre om marken består av massor med "kullar" och "dalar" (dvs flera konkava/konvexa skarvar) under fordonet. Jag håller på att skissa på en mer generell algoritm på det. Får se om jag kommer på nåt innan nån annan kläcker en smart lösning. Jag tenderar till att krångla till saker så oddsen är väl stor :)

Griff
snappahead

AndersO

Jovisst.. Ju mer realistiskt man vill ha det desto krångligare.

Med metoden som jag beskrev så står man hela tiden på en jämn yta.. eftersom man räknar ut ett plan från 3-4 punkter, fordonets/objektets hörn (projjicerade rakt ner mot marken). Man kommer ju att missa "gupp/gropar" som är mindre än fordonet.. Och fordonet kommer hela tiden vara "slickat" jäms med marken (eller det uträknade planet). Och de kommer bara att fungera på heightmaps. Har man grottor eller dylikt så blir de lite knepigare.

Håller på med att gå igenom den här tutorialen:
http://www.d6.com/users/checker/dynamics.htm

Den kan kanske vara till hjälp, men rätt mycke krånglig matematik. Tycker jag iaf. :)



ââ,¬Å"I will make weapons from your booones!!ââ,¬Â

Lupson

Tack för era svar. Jag tror att jag ska börja med att strunta i den konvexa (? de "svåra" vinklarna) problematiken och försöka med normalmetoden baserat på ett plan som utgår från fyra "hjulpunkter". Jag tror jag vet hur man implementerar den metoden.

Kvällen fick dessvärre ägnas åt att åtgärda en generalbugg i 3ds-laddaren så det blev inget matematikpulande ikväll. Men på den positiva sidan så fick jag texturerat några modeller (och texturerna ritade på rätt plats!) så några nya screenshots finns att betitta på: http://w3.adb.gu.se/~s99luppe/openGL/screenshots

Är extra nöjd med heli_gfxfel.jpg - ganska snygg Hind och grafikfel i samma bild!

/Lupson
Mvh Lupson - kortklippt.

"Kustartilleriet fördröjer fienden i kustbandet till militär hjälp kan anlända".
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Core i5 E3570K - Fractal Design Define Mini - Sapphire R290 Tri-X