The Problem
I am trying to use the Kabsch algorithm to find the optimal rotation between two sets of 4 points, but the errors I am getting are unacceptably large. I want to map the red points (P) into the blue points (Q), shown here.
What I've tried
Here is my implementation of the Kabsch algorithm, given numpy arrays of the mapping_points (P) and true_points (Q)
mapped_centroid = np.average(mapping_points, axis=0)
true_centroid = np.average(true_points, axis=0)
mapping_points -= mapped_centroid
true_points -= true_centroid
h = np.matmul(mapping_points.T, true_points)
u, s, v = np.linalg.svd(h)
d = np.linalg.det(v @ u.T)
e = np.array([[1, 0, 0], [0, 1, 0], [0, 0, d]])
r = v @ e @ u.T
tt = true_centroid - np.matmul(r, mapped_centroid)
I then apply the mapping to the centroid-adjusted points in P:
map_list = []
for i in mapping_points:
point = np.matmul(r, i) + tt
map_list.append(np.reshape(point, (1, 3)))
mapped_xyz = np.vstack(map_list)
However, plotting the mapped_xyz and true_points gives very inaccurate results shown in the above plot. Any ideas on what I've done wrong?
Additional information
I am actually trying to map between 2 networks of several hundred nodes. One network is the "true positions", the other is a "relative map" of the network. I am using the anchors nodes Q and the corresponding points P to find the best transformation, and then map the rest of the nodes.
I have noticed that there is a strong sensitivity to the choice of anchor nodes (which I am sampling at random). With only 3 anchor nodes, the mapping is occasionally close, sometimes off by a single rotation, sometimes mirrored about the z-axis. I have been banging my head against the wall trying to figure this out. Any help is greatly appreciated.
Edit
Here is the data for the points Q and P used in the above plot.
Q = [[ 1774.11606309 -4241.11341178 5259.04277742]
[ 6079.70499031 -98.14197972 -3442.0914569 ]
[ 813.07069876 3334.26289147 -6112.55652513]
[ 1856.72080823 2328.86927901 6322.16611888]]
P = [[ 3172.79468418 727.52462347 7122.70450243]
[ 165.28953155 -3552.32467068 -2045.15346584]
[ 5292.45250241 -1748.52037006 -6181.40300009]
[ 1893.07584225 5897.19719625 3130.41287776]]