webForumDet fria alternativet

Rotera vertiser runt origo

Programmering

30 svar · 1 205 visningar · startad av Alpha II

Medlem sedan maj 20002 993 inlägg
Frågan#1

Hur roterar jag en punkt (3D) runt origo tex 10 grader runt x-axeln? Det jag vill veta är den nya positionen.

Medlem sedan juni 200010 432 inlägg
#2

Ah! Har just gått en mattekurs i ämnet (linjär algebra). :D

Det du bör göra är att ta reda på rummets baser (troligen är det standardbasen du behöver) och bygg en matris med förhållandet

|x| | 1   0     0    |
|y| | 0  cos@  sin@  |
|z| | 0 -sin@  cos@  |

@ = vinkeln i radianer

När du har matrisen är det bara att multiplicera punkens vektor från origo med matrisen, så får du en ny vektor vars koordinater är den punkten du söker.

Hittade lite länkar som kanske är mer illustrativa:
http://www.makegames.com/3drotation/
http://mathworld.wolfram.com/RotationMatrix.html

Om dessa länkar inte räcker, googla lite om 'rotation matrix' eller 'rotations matriser'. Det finns nog en hel del förklaringar även på svenska då detta är en linjär avbildningssmatris och ingår i kurser om linjär algebra på universitetsnivå :)

Medlem sedan maj 20002 993 inlägg
#3

Jag hittade en sida igår på gamedev som gick igenom olika matriser väldigt enkelt.

Idag har jag försökt att testa vad jag läste. Någon sorts rotation blir det väl, men kuben som jag just nu testar med blir helt platt på ett visst ställe!

Jag har bifogat programmet så ni kan se vad jag menar.

Koden för att rotera vertiserna ser ut så här:

  for I := 0 to 7 do begin
    vertice[i,0] := cubevert[i,0]*10;
    vertice[i,1] := cubevert[i,1]*10;
    vertice[i,2] := cubevert[i,2]*10;

    // X-rot
    vertice[i,1] := vertice[i,1] * cos(Xrot) + vertice[i,2] * (-sin(Xrot));
    vertice[i,2] := vertice[i,1] * sin(Xrot) + vertice[i,2] * cos(Xrot);

    // Y-rot
    vertice[i,0] := vertice[i,0] * cos(Yrot) + vertice[i,2] * sin(Yrot);
    vertice[i,2] := vertice[i,0] * (-sin(Yrot)) + vertice[i,2] * cos(Yrot);

    // Z-rot
    vertice[i,0] := vertice[i,0] * cos(Zrot) + vertice[i,1] * (-sin(Zrot));
    vertice[i,1] := vertice[i,0] * sin(Zrot) + vertice[i,1] * cos(Zrot);

  end;
Medlem sedan juni 200010 432 inlägg
#4

Det där ser mer ut som en 2D rotation. Om du ska rotera runt x axeln så måste du sätta x koordinaten till 1 i rotationsmatrisen och y samt z till 0. (se min matris ovan). En annan detalj som kan fela är vad Xrot har för värde... är det i radianer eller vad?

Medlem sedan maj 20002 993 inlägg
#5

Ja det är radianer.

Jag tycker att jag verkar använda samma rotations matriser som beskrivs på http://www.gamedev.net/reference/articles/article877.asp

Medlem sedan juni 200010 432 inlägg
#6

Varför de använder 4x4 matriser vet jag inte (3D är ju detsamma som rummet, och rummet definieras i R^3), men om du tittar på deras rotationsmatris så är den lika med det jag visade några inlägg högre upp. Dvs att de koordinater som motsvarar den axel du ska roterar runt, ska inte ändras. Således sätts X till 1 i den matrisen. Hade du roterat runt exempelvis Z axeln ska Z sättas till 1. (I matrisen som omvandlar koordinater! Inte att koordinaten X ska sättas till 1).

I ditt fall borde det ge att X inte ska räknas, så du kan testa att kommentera bort de raderna!

Medlem sedan maj 20002 993 inlägg
#7

Du har nog missförstått min kod.
När vertiserna roteras runt x-axeln ändras aldrig x. Positionen för x för vertis nummer n är vertices[n,0] och jag ändrar bara på 1 och 2 (y resp. z).

Jag har tyvärr inte hunnit läsa igenom dina länkar än men jag kommer att göra det när jag har tid. :)

Medlem sedan juni 200010 432 inlägg
#8

Alpha II skrev:

Du har nog missförstått min kod.
När vertiserna roteras runt x-axeln ändras aldrig x. Positionen för x för vertis nummer n är vertices[n,0] och jag ändrar bara på 1 och 2 (y resp. z).

Okej, jo då har jag nog missförstått koden. Jag läste koden som att du kör allt som stod, inte att det var exempel med valbara delar.. :)

Men jag undrar om det inte för x-rotation istället borde vara:

vertice[i,1] := vertice[i,1] * cos(Xrot) + vertice[i,2] * sin(Xrot);
vertice[i,2] := vertice[i,1] * (-sin(Xrot)) + vertice[i,2] * cos(Xrot);

Anledningen till det är att man multiplicerar matrisen som transformerar med vektorn som ska transformeras och inte tvärtom. Dvs:

T x u. Då T är matrisen jag gav några inlägg ovanför och u den koordinat som ska flyttas. Mattepseudo:


| a11 a12 |  |u1|          |a11*u1 + a12*u2|
| a21 a22 |  |u2|    =>    |a21*u1 + a22*u2|
Medlem sedan maj 20002 993 inlägg
#9

Resultatet blir ändå något som mer liknar skärmsläckaren mystify än en roterande kub :l

Jag har även kollat igenom sidorna du länkade till, men komplicerad engelska och mattematik gör att jag inte förstod mycket mer än jag redan gjorde.
Sen att 3D matriser oftast är 4x4 antar jag beror på att annars kan inte "model view" matrisen "translatas", dvs att positionen flyttas.

Tex:

1  0  0  x
0  1  0  y
0  0  1  z
0  0  0  1
Medlem sedan juni 200010 432 inlägg
#10

Alpha II skrev:

Sen att 3D matriser oftast är 4x4 antar jag beror på att annars kan inte "model view" matrisen "translatas", dvs att positionen flyttas.

Okej. Men för att använda en rotationsmatris ska man ivf göra som jag skrev. Det kanske är nåt annat som förbisetts? Om det exempelvis är koordinater som ligger utanför det koordinatsystemet som motsvarar skärmen behöver du göra ytterligare transformeringar (översättning mellan koordinatsystemen).. dvs om du räknar nya koordinater i ett "virtuellt" koordinatsystem kan man inte direkt översätta dem i ett reellt dito, eftersom det är olika baser (de vektorer som spänner upp ett koordinatsystem/rum). Alltså, om du har ett koordinatsystem som motsvarar skärmen med (0,0) i vänstra hörnet, så kan du inte rotera själva objketet utan att omvandla koordinatsystemet om det är kuben som ska roteras runt sin egna axel.

Medlem sedan maj 20002 993 inlägg
#11

Jag är inte helt säker på vad du menar nu.

Min kub är definierad såhär:

  cubevert: array[0..7] of TPoint3 = (
        ( 10.0,  10.0, 10.0),
        ( 10.0, -10.0, 10.0),
        ( -10.0,-10.0, 10.0),
        ( -10.0, 10.0, 10.0),
        ( 10.0,  10.0, -10.0),
        ( 10.0, -10.0, -10.0),
        ( -10.0,-10.0, -10.0),
        ( -10.0, 10.0, -10.0));

Sen har jag en "kamera" som är en vektor som vars x och y har värdet av fönstrets mittpunkt.

Sen när kuben målas lägger jag till kamerans position till vertisernas position.

Har du testat programmet jag laddade upp? Jag kan inte förstå vad som blir fel. :l

Medlem sedan juni 200010 432 inlägg
#12

Alpha II skrev:

Sen har jag en "kamera" som är en vektor som vars x och y har värdet av fönstrets mittpunkt.

Sen när kuben målas lägger jag till kamerans position till vertisernas position.

Hmm... är det månne här det blir fel? En rotation går ju i rummets (kubens) koordinatsystem. Så origo för kuben är inte detsamma som för skärmen eller vad det nu är som definieras som utritat koordinatsystem.

Har du testat programmet jag laddade upp?

Nej, det har jag tyvärr inte. Det jag försökt mig på här är att visa den matematiska tolkningen i vad som händer. Men okej, jag ska vid tillfälle se om jag kan köra koden i min maskin (sitter inte vid den nu). :)

Medlem sedan feb. 20016 388 inlägg
#13

Att rotera 3D-föremål som t.ex. kuber är lite annorlunda än att "bara" rotera en punkt. Jag får lite huvudvärk när jag försöker sätta mig in i det ;), men det finns massor att läsa här:

http://www.gamedev.net/reference/articles/article1279.asp

Medlem sedan maj 20002 993 inlägg
#14

Woah, med hans sfäriska kordinatsystem, helkonstiga namngivelser för dimensions axlarna (Y,Z,X ordnade han dem visst) och bakvänd ordning för att multiplicera matriser blev det inte enklare att förstå, hehe ;)

Sånt här skulle jag hellre gå igenom i skolan istället för att rita grafer över hur en fiskgratängs temperatur sjunker o stiger när den placeras i en ugn. :OO

Går det med "model view" matriser att bara lägg på (multiplicera?) alla rotationer och transformeringar man gör, och sedan bara gångra den slutgiltiga matrisen med varje punkt?

Medlem sedan maj 20002 993 inlägg
#15

Jag kollade igenom texten snabbt ännu en gång. Tror jag förstog mer nu. Men det skulle vara enklare om han hade använt normala kordinater (X,Y,Z). Ska testa någon dag då min "musarm" eller vad denna smärta i mushanden nu än är har gått över.

Medlem sedan maj 20002 993 inlägg
#16

Kunde inte låta bli så jag testade det direkt. ;) Det fungerade :D Är i och för sig inte helt hudra på varför...

Var felet jag gjorde innan att jag multiplicerade matris för matris (X,Y och Z rotations matriserna) istället för att skapa en matris som jag sedan multpilcerade vektorn med?

Medlem sedan juni 200010 432 inlägg
#17

Går det med "model view" matriser att bara lägg på (multiplicera?) alla rotationer och transformeringar man gör, och sedan bara gångra den slutgiltiga matrisen med varje punkt?

Model view matriser är bara en utbyggnad. En avbildningsmatris är som en funktion. Genom att multiplicera matrisen mot en given vektor får du en ny vektor. Simple as that :)

Lite mer matematiskt utryckt:
Ditt 'problem' är att du har ett koordinatsystem som är själva kuben och ett annat koordinatsystem som är själva utritningsytan. Så för att översätta koordinaterna behövs det förutom en rotationsmatris (som gäller för kubens koordinatsystem), även en s.k 'basbytesmatris' som gör om en kubens koordinater till motsvarande i det andra koordinatsystemet. Man får då två matriser som kan slås ihop till en matris som nu blir den nya transformeringsmatrisen.

Medlem sedan maj 20002 993 inlägg
#18

Njae, mitt enda problem just nu är att min kod (rotations matris) inte verkar bry sig så mycket om hur jag vill att kuben ska rotera utan snurrar lite fram o tillbaka. Sätter jag t ex x rotationen till noll roteras ändå kuben kring x-axeln. Att enbart sätta ett värde som rotation i antingen Y- eller Z-axeln får samma resultat.

Medlem sedan maj 20002 993 inlägg
#19

:e

Medlem sedan juni 200010 432 inlägg
#20

Kul :)

265 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
124 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)