2017-06-04 74 views
0

我正在做一個模擬遊戲,我不是很擅長三角學,也不知道如何做到這一點,儘管許多嘗試。「反轉」這些數學觸發(3d遊戲世界)操作

我在3D世界的某個位置有一些面向角(z角)的車輛。我旁邊還有一個對象,並且有XYZ位置和旋轉。我想將對象附加到車輛上,但要附加它,我需要指定相對於車輛的偏移量,而不是現實世界的位置。 這是「車輛座標系統」: vehicle attachment coords

但這不是問題。我已經有這個代碼做的:

new Float:ofx, Float:ofy, Float:ofz, Float:ofangle; 
new Float:attachX, Float:attachY; 
new Float:vehX, Float:vehY, Float:vehZ, Float:vehAngle; 

GetVehiclePos(vehicleid, vehX, vehY, vehZ); // get vehicle XYZ pos 
GetVehicleZAngle(vid, vehAngle); // get vehicle facing angle 
ofx = x-vehX; // x = object's real world XYZ, vehX - vehicle's XYZ. Calculate   real world offset between object and vehicle 
ofy = y-vehY; 
ofz = z-vehZ; 
ofangle = rz-vehAngle; 
// calculate attach offsets relative to vehicle (see image above) 
attachX = ofx*floatcos(vehAngle, degrees) + ofy*floatsin(vehAngle, degrees); 
attachY = -ofx*floatsin(vehAngle, degrees)+ ofy*floatcos(vehAngle, degrees); 

AttachObjectToVehicle(objectid, vehicleid, attachX, attachY, ofz, rx, ry, ofangle); // attach object with calculated X, Y and angle 

而這個偉大的工程,但我想現在要做的,就是「反轉」這一點。 我想計算對象的真實世界位置(所以它會在完全相同的地方,因爲它是現在,但不要執着) 所以我有這樣的:

new Float:vehX, Float:vehY, Float:vehZ, Float:vehAngle; 
GetVehiclePos(vehicleid, vehX, vehY, vehZ); 
GetVehicleAngle(vehicleid, vehAngle); 

new Float:objAttachX, Float:objAttachY, Float:objAttachZ, Float:objAttachRotX, Float:objAttachRotY, Float:ObjAttachRotZ); 
GetAttachedObjectOffsets(objectid, objAttachX, objAttachY, objAttachZ); 
GetAttachedObjectRotation(objectid, objAttachRotX, objAttachRotY, objAttachRotZ); 
// now, using current vehicle position and the object's attachment offsets, somehow calculate the objects position in real world. 

我會很高興,如果有人可以幫助我在這裏,我想這很簡單,但我無法弄清楚。

回答

0

忘掉三角。你所要做的就是求解一個具有2個未知數(2個參數c和s)的2個線性方程組: (分別乘以s和c): s X = scx + s^2 y c Y = -scx + c^2 y。 加上: s x + c Y = s^2 y + c^2 y = y [cos^2 + sin^2 = 1] 同樣對於x: c X = c^2 x + scy s Y = -s^2 x + scy, 產生: c X -s Y = c^2 x + s^2 x = x

0

如果您使用車輛轉換矩陣(4乘4矩陣),因爲它將具有比例,世界座標和旋轉。

// example of identity matrix 
mat = [[1,0,0,0], 
     [0,1,0,0], 
     [0,0,1,0], 
     [0,0,0,1]] 

做出如下更容易理解,我會重新命名矩陣陣列項目 如墊[0,0]成爲XAX和墊[0,1]是XAY

// not code just a representation of named array items 
[ [ xAx,xAy,xAz,0 ] // xA is the x axis x,y,z as scaled vector 
    [ yAx,yAy,yAz,0 ] // yA is the y axis x,y,z as scaled vector 
    [ zAx,zAy,zAz,0 ] // yA is the z axis x,y,z as scaled vector 
    [ ox ,oy , oz,1 ] ] // o is the coordinate of the local origin. 

這保持爲真對於所有4乘4矩陣(除了最終視圖投影)

因此,您有附加對象pos x,y,z位置。如果你有一個矩陣庫,你只需將vec的位置乘以對象的矩陣pos * mat來獲得位置。

localPos = {x : ?, y : ? , z : ?}; // The position of the mounted object 
worldPos = {x : ?, y : ? , z : ?}; // the new calculated position we are after 
// lp for localPos to save typing 
// wp for worldPos 
// Using the matrix named variables 

wp.x = lp.x * xAx + lp.y * yAx + lp.z * zAx + ox; 
wp.y = lp.x * xAy + lp.y * yAy + lp.z * zAy + oy; 
wp.z = lp.x * xAz + lp.y * yAz + lp.z * zAz + oz; 

而你有世界座標。

要做到這一點,使用vec3矩陣數組[0,0,0]和矩陣作爲4乘4平面陣列[0,0,0 ...,0] 16項長。

wp[0] = lp[0] * mat[0] + lp[1] * mat[4] + lp[2] * mat[8] + mat[12]; 
wp[1] = lp[0] * mat[1] + lp[1] * mat[5] + lp[2] * mat[9] + mat[13]; 
wp[2] = lp[0] * mat[2] + lp[1] * mat[6] + lp[2] * mat[10] + mat[14]; 

或者,如果你已經超負荷向量和矩陣乘法那麼它是

Vector localPos = ? // get the object position in vehicle local space 
Matrix mat = ? // get the local vehicle transform 

Vector worldPos = localPos * mat; 
一樣簡單