how to calculate a rilative position from a global position

Hello,
in monogame i have a world matrix
WorldMatrix= Matrix.CreateWorld(Vector3.Zero,Vector3.Forward,Vector3.Up)
that is used for the BasicEffect
then it can be transformed and rotated by Matrix.CreateTranslation and CreateRotationX&Y&Z

so newWorldMatrix = WorldMatrix * Trans * RotX * RotY * RotZ

Trans transforms the WorldMatrix to desired posithion “newOrigin”
while RotX * RotY * RotZ create Pitch, yaw, and roll rotation

and if i have a position “globalPos” vector from the WorldMatrix
how to calculate the equivalent of that position vector from the newWorldMatrix in it’s xyz directions

for an example if globalPos = (1,1,1) and newOrigin(0.1,1.1,0) and the rotation matrices has rotated the local world axis 90d around Y clockwise
the relativePos is (1,-0.1,-0.9)

this what i could come up with

 public static Vector3 GetRelativePosition(int i, Vector3 globalPos)
        {
            List<Bone> BonesA = BonesList();
            Transform3D boneTransform = new Transform3D();
            boneTransform.rotOrder = rotOrder;
            boneTransform.position = new Vector3D(BonesA[i].Translation);
            boneTransform.setRotationInRad(new Vector3D(BonesA[i].Rotation));
            boneTransform.scale = new Vector3D(BonesA[i].Scale);

            Vector3D newOrigin = boneTransform.getGlobalOrigin();
            Matrix3D parentTrans = Matrix3D.generateTranslationMatrix(newOrigin.X, newOrigin.Y, newOrigin.Z);
            Matrix3D parentRot = boneTransform.getGlobalRotation();
            Matrix3D boneWorld = Matrix3D.CreateWorld(new Vector3D(0, 0, 0), new Vector3D(0, 0, -1), new Vector3D(0, 1, 0)) * parentTrans * parentRot;

            Vector3D relativePos = Matrix3D.matrixTimesVector3D(boneWorld, new Vector3D(globalPos.X - newOrigin.X, globalPos.Y - newOrigin.Y, globalPos.Z - newOrigin.Z));
            return new Vector3((float)relativePos.X, (float)relativePos.Y, (float)relativePos.Z);
        }

for more context my editor draws a skeletal hierarchy transform
Transform3D calculates the global position of every object/bone using the relative position from the hierarchy
using getGlobalOrigin() and getGlobalRotation() to calculate the position and orientation of the any opject relative to it’s parent
Matrix3D and Victor3D works in a similar way to XNA Matrix and Victor3
i want t be able to calculate the relative position from the global position so i can add more bones and position them at the global position
I cant really wrap my head around the requerd math to do this , thanks

the example upove should look like this
the new opject is drawn at (1,1,1) while it’s relative position is (1,-0.1,-0.9)

You can invert a matrix to make it do the opposite. If you have a matrix that transforms local positions to world positions, then the inverse of that matrix will transform world positions to local positions.

3 Likes

i was able to use matlab to figure out the right math to do this, some times it works and gives the right answer
but some times it dosn’t calculate the rotation right . but i can work with that

% Define position A and B as 3D vectors
newOriPos = [0, 1, 0];
globalPos = [1, 1, 1];

Body = globalPos - newOriPos;

% Define rotation angles (in degrees)
theta = 0; % no rotation around X-axis
beta = 90; % rotate 90 degrees around Y-axis
gamma = -90; % rotate 90 degrees around Z-axis

% Define rotation matrices
Rx = [1, 0, 0;
0, cosd(theta), -sind(theta);
0, sind(theta), cosd(theta)];

Ry = [cosd(beta), 0, sind(beta);
0, 1, 0;
-sind(beta), 0, cosd(beta)];

Rz = [cosd(gamma), -sind(gamma), 0;
sind(gamma), cosd(gamma), 0;
0, 0, 1];

% Apply rotations in order: Z, Y, X
%parentRot = Rz * Ry * Rx;
M = [1, 0, 0, 0; 0, -4.371139E-08, 1, 0; 0, -1, -4.371139E-08, 0; 0, 0, 0, 1];

parentRot = M(1:3,1:3)'; % transpose to convert from row-major to column-major


% Rotate vector C
relativePos = parentRot * Body';


% Display the result
disp(relativePos);

you were provided correct, 100% working, production proven solution by Markus, what’s the motivation behind marking your approach that “sometimes works” as a solution and why is it becoming trend on this forum?

1 Like

i didn’t use the matrix inverse though , i just calculated the vector between the two positions and ther rotate that vector with the rotation matrix . but 30% of the times i have tried it , i get an inverted XZ components but since i have provided a way to edit the relative position in my program this dosn’t make a big problem

when i got the chance i was able to understand the matrix inverse method , and it was a 100% success

 Matrix3D invRot = Matrix3D.invert(parentRot);
                            Matrix3D invTrans = Matrix3D.invert(parenttrans);
                            Matrix3D relativetrans = invRot * invTrans;
                            Vector3D relativePos3 = Matrix3D.matrixTimesVector3D(relativetrans, globalPos);
1 Like