"反向"这些数学三角(3D游戏世界)操作

时间:2017-06-04 08:19:24

标签: math trigonometry

我正在为一个游戏做一个mod并且我对三角测量不是很好,并且尽管经过多次尝试仍无法弄清楚如何做到这一点。

我在3D World中有一辆车在某个位置有一些面对角(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.

如果有人可以帮助我,我会很高兴,我觉得这很简单,但我无法弄清楚。

2 个答案:

答案 0 :(得分:0)

忘掉三角学。您所要做的就是求解一个包含2个未知数的2个线性方程组(以及2个参数,c和s): X = x * c + y * s Y = -x * s + y * c 相当于(分别乘以s和c): s X = s c x + s ^ 2 y c Y = -s c x + 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 + s c y s Y = -s ^ 2 x + s c y, 收益: c X - s Y = c ^ 2 x + s ^ 2 x = x

答案 1 :(得分:0)

如果您使用车辆变换矩阵(4乘4矩阵),那将是最简单的,因为它将具有比例,世界坐标和旋转。

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

为了使下面的内容更容易理解,我将重命名矩阵数组项 例如,mat [0,0]变为xAx,mat [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;