我正在为一个游戏做一个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.
如果有人可以帮助我,我会很高兴,我觉得这很简单,但我无法弄清楚。
答案 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;