Change from one cartesian 3D co-ordinate system to another by translation and rotation

just like parent and child,

I wanted to do it from scratch

any math behind?

I recommend Freya’s courses on the matter. The other ones too, but what you’re looking for is around this time:

https://www.youtube.com/watch?v=XiwEyopOMqg

1 Like

Give me a reason to bother explaining anything to someone with this kind of attitude?

It is not something secret, and the video is likely on point.

4 Likes

sorry :stuck_out_tongue:

found this

def change_basis(coords, new_basis, old_basis):
‘’’
Change the basis of coordinates to a new basis. In a regular structure
we have the coordinates in the regular cartesian coordinate system. For helix-helix
orientations, however, we want to express the coordinates in a coordinate system
defined by the first helix.

The new basis will consist of the axis of the first helix, one of its twist elements
(the one closest to the second vector) and a third vector orthogonal to the previous
two.

Error - Page Missing

@ coords: The coordinates to transform (array of n elements).
@ new_basis: The new basis vectors (n x n matrix)
@ old_basis: The old basis for the coordinates(n x n matrix)
@return: The new coordinates according to the new basis
‘’’
#assert(len(coords) == len(new_basis))
#assert(len(new_basis) == len(old_basis))

dim = len(coords)
#print “coords:”, coords
standard_coords = np.dot(old_basis.transpose(), coords)
‘’’
#print “standard_coords:”, standard_coords
standard_to_new = inv(new_basis.transpose())
#print “standard_to_new:”, standard_to_new
new_coords = np.dot(standard_to_new, standard_coords)
print “new_coords:”, new_coords
‘’’

new_coords = nl.solve(new_basis.transpose(), standard_coords)
#print “new_coords1:”, new_coords1

return new_coords

Nope. Overly complicated and slow due using solver.

Watch the video from earlier, and apologize to its author.

sorry sorry I’m really sorry :frowning: I’m crying I apologize to all of you and to the author, it’s a good video, I was wrong, I thought that was a troll video, really sorry I remove what I said

Good. Now, back to the topic.

The matrix is LITERALLY basis vectors and position packed into a matrix.

“Transform” matrix denotes how the new coordinate system is represented within the old one.
Meaning, as long as it is not a projection matrix, a matrix stores “xAxis vector”, “yAxis vector”, “zAxis vector” and “position”.

The reset depends on used notation. For example, I believe directx used row major matrix layout in documentation:

u.x u.y u.z 0
v.x v.y v.z 0
w.x w.y w.z 0
p.x p.y p.z 1

So, if your matrix only translates, then it will be

  1   0   0 0
  0   1   0 0
  0   0   1 0
p.x p.y p.z 1

If it only rotates, it will be:

u.x u.y u.z 0
v.x v.y v.z 0
w.x w.y w.z 0
 0   0   0  1

And if it only scales, it will be:

sx 0  0  0
0  sy 0  0
0  0  sz 0
0  0  0  1

Where sx/sy/sz are scale factors for each axis.

You also can do skew, and combine all transforms in one. Scale is length of each axis vector, rotation is determined by where the vectors are pointing and so on.

That only works as long as it is not a projection matrix. Meaning there’s distinct 0 0 0 1 pattern in the rightmost column (in row-major representation anyway)

Vector3 Multiply(Vector3 a, Vector3 b)
{
return new Vector3(a.x * b.x, a.y * b.y, a.z * b.z);
}
Vector3 Transform2( Vector3 vector, Quaternion rotation)
{
float x = rotation.x + rotation.x;
float y = rotation.y + rotation.y;
float z = rotation.z + rotation.z;
float wx = rotation.w * x;
float wy = rotation.w * y;
float wz = rotation.w * z;
float xx = rotation.x * x;
float xy = rotation.x * y;
float xz = rotation.x * z;
float yy = rotation.y * y;
float yz = rotation.y * z;
float zz = rotation.z * z;

return new Vector3(
vector.x * (1.0f - yy - zz) + vector.y * (xy - wz) + vector.z * (xz + wy),
vector.x * (xy + wz) + vector.y * (1.0f - xx - zz) + vector.z * (yz - wx),
vector.x * (xz - wy) + vector.y * (yz + wx) + vector.z * (1.0f - xx - yy));
}

void WorldToLocal( Transform parentboss,Transform other, out Vector3 rp,out Quaternion rq, out Vector3 rs)
{
Vector3 invScale = parentboss.localScale;
if (invScale.x != 0.0f)
invScale.x = 1.0f / invScale.x;
if (invScale.y != 0.0f)
invScale.y = 1.0f / invScale.y;
if (invScale.z != 0.0f)
invScale.z = 1.0f / invScale.z;

Quaternion invRotation = new Quaternion(-parentboss.rotation.x, -parentboss.rotation.y, -parentboss.rotation.z, parentboss.rotation.w);

rq = (invRotation* other.rotation).normalized;
rs= Multiply(other.localScale, invScale);
Vector3 tmp = other.position - parentboss.position;
rp=Transform2(tmp, invRotation);
rp=Multiply(rp, invScale);
}

Vector3 tt;
void OnDrawGizmos()
{
Transform p1=GameObject.Find(“GameObject (1)”).transform;
Transform p2=GameObject.Find(“GameObject (2)”).transform;
if (!tt.Equals(p1.position))
{
Vector3 rp;
Quaternion rq;
Vector3 rs;
WorldToLocal(p1, p2, out rp, out rq, out rs);
// LocalToWorld(p1, p2,out rp,out rq,out rs);
p2.position = rp;
p2.rotation = rq;
p2.localScale = rs;
tt = p1.position;
}
}

not working it’s killing me, it’s been more than 30 hours now, the gameobject transform p2 become truly a child of p1 but behaves weirdly

Nope.
“return rotation * vector”
https://docs.unity3d.com/ScriptReference/Quaternion.html
https://docs.unity3d.com/ScriptReference/Quaternion-operator_multiply.html

Nope.

Transform.worldToLocalMatrix
https://docs.unity3d.com/ScriptReference/Transform-worldToLocalMatrix.html

Additionally see:
https://docs.unity3d.com/ScriptReference/Matrix4x4.html
https://docs.unity3d.com/ScriptReference/Matrix4x4-rotation.html

You could LITERALLY multiply other.localToWorldMatrix with parentboss.worldToLocalMatrix, then extract components. And you wouldn’t even need to do that if other was parented to parentboss in the first place.

And so on.

Currently you’re making your life more difficult by not reading documentation.