Just lately I am engaged on handtracking ARs. To align 3D fashions to arms, I needed to match coordinates of 3D mannequin objects to a coordinate of a hand to make results like 3D fashions on a hand and so on.

It’s a bit difficult to align them, so let me clarify methods to do it right here.

For example we now have a goal coordinate XYZ (e.g. hand) and a coordinate xyz (e.g. 3D mannequin) to align. We already know the vectors of XYZ and xyz. X/Y/Z are orthogonal one another and normalized (the size is 1) and x/y/z are additionally. The purpose is to align the xyz vectors to XYZ.

**Aligning the origin positions are usually not defined on this article as a result of we will do it simply by setting the XYZ origin place to xyz origin place.**

*Within the following steps, I align z/Z and x/X. Nonetheless, the order of operation doesn’t matter. Chances are you’ll align y/Y first and z/Z subsequent.*

First, let’s align the z axis.

Calculate the cross vector `z × Z`

and θ with the dot product and Arccosine which is used to rotate the coordinate across the cross vector. To attain the rotation, we will use a quaternion. Calculating quaternion by ourselves is a bit difficult and often 3D CG engine has built-in operate to calculate it from the axis to rotate round and the angle. *When you actually need to implement by your self, it’s possible you’ll refer this article.*

That is an instance pseudocode. Your programming language / 3D CG engine (e.g. Three.js / Unity / Unreal Engine) ought to have cross / dot / normalize / acos / fromAxisAngle.

```
Vec3 z = ... // Your z
Vec3 Z = ... // Your Z
Vec3 axisZ = normalize(cross(z, Z)); // Normalized cross vector.
float angleZ = acos(dot(z, Z)); // The angle between z and Z --> theta within the picture.
Quaternion qz = fromAxisAngle(axisZ, angleZ); // Later we are going to make different quaternions so let's title it qz.
```

Now we have got the quaternion `qz`

to align z to Z axis.

By making use of the quaternion `qz`

to your coordinate, it’s best to have x’/y’/z’ like the next picture.

Aligning x/X axes is mainly the identical course of as we did for z/Z. Nonetheless, please don’t forget apply the quaternion `qz`

to the x vector. Let’s title the rotated x vector as `x'`

.

Pseudocode ought to be like this. `applyQuaternion`

is a operate to use a quaternion to a vector. Your programming language / 3D engine ought to have an equal.

```
Vec3 rotatedX = applyQuaternion(x, qz); // x'
Vec3 X = ... // Your X
Vec3 axisX = normalize(cross(rotatedX, X));
float angleX = acos(dot(rotatedX, X)); // The angle between x' and X --> phi within the picture
Quaternion qx = fromAxisAngle(axisX, angleX);
```

We have got the following quaternion `qx`

.

Now we now have `qz`

and `qx`

. By combining the quaternions, we can have the ultimate quaternion we will notice our coordinate alignment.

`multiplyQuaternions`

is a operate to mix two quaternions into one. Your programming language / 3D engine ought to have an equal. Please watch out that the order of `qz`

and `qx`

is vital.

```
Quaternion q = mltiplyQuaternions(qz, qx);
```

By making use of the quaternion `q`

to x/y/z respectively, you will get vectors similar to X/Y/Z.

I confirmed pseudo code within the above. I additionally offer you guys an instance in Three.js.

```
// Your coordinates.
// x/y/z are vectors that will likely be aligned FROM.
const x = new Vector3(...);
const y = new Vector3(...);
const z = new Vector3(...); // <-- You don't want this really.
// X/Y/Z are vectors that will likely be aligned TO.
const X = new Vector3(...);
const Y = new Vector3(...);
const Z = new Vector3(...); // <-- You don't want this really.
const axisZ = z.clone().cross(Z).normalize();
const angleZ = Math.acos(z.dot(Z));
const qz = new Quaternion().setFromAxisAngle(axisZ, angleZ);
const rotatedX = x.clone().applyQuaternion(qz);
const axisX = rotatedX.clone().cross(X).normalize();
const angleX = Math.acos(rotatedX.dot(X));
const qx = new Quaternion().setFromAxisAngle(axisX, angleX);
// Remaining quaternion
const q = new Quaternion().multiplyQuaternions(qz, qx);
// You need to use q like this.
yourModel.rotation.setFromQuaternion(q)
```