0

(Rewritten, compressed and partly corrected version)

I try some trivial rotation of a triangle in 3d to point its normal straight up without any distortion. I'm following this post calculate-rotation-matrix-to-align-vector, but for some reasons, my result is undesirable and I can't see the error in my code or my error in reasoning. My Python code as followed:

# defining the triangle with three points in 3d space (xyz)
v1 = [1,1,1]
v2 = [2,2,2]
v3 = [2,1,3]

# calculating the normal and converting to unit-vector
n = np.cross( np.subtract(v2,v1), np.subtract(v3,v1) )
a = n / np.sqrt( n[0]**2 + n[1]**2 + n[2]**2 )
b = [0,1,0] 

v = np.cross(a,b)
s = np.sqrt(v.dot(v))
c = np.dot(a,b)

Vx = np.array([
    [  0  , -v[2], v[1] ],
    [ v[2],   0  , -v[0]],
    [-v[1],  v[0],   0  ]
])
Vx2 = Vx.dot(Vx)
I = np.identity(3)
iv = (1/(1+c))

# single rotation matrix
R = np.add(I, np.add(Vx, np.multiply(Vx2,iv)))

Then calculating the centroid, the rotation matrix as described and also as separated matrices as explained here Rotating a Vector in 3D Space

cx = (v1[0]+v2[0]+v3[0]) / 3.0
cy = (v1[1]+v2[1]+v3[1]) / 3.0
cz = (v1[2]+v2[2]+v3[2]) / 3.0

v1t = [v1[0]-cx,v1[1]-cy,v1[2]-cz]
v2t = [v2[0]-cx,v2[1]-cy,v2[2]-cz]
v3t = [v3[0]-cx,v3[1]-cy,v3[2]-cz]

As well as the single rotation matrices:

rz = np.array([
    [c,-s, 0],
    [s, c, 0],
    [0, 0, 1]
])

ry = np.array([
    [ c, 0, s],
    [ 0, 1, 0],
    [-s, 0, c]
])

rx = np.array([
    [1, 0, 0],
    [0, c,-s],
    [0, s, c]
])

rxyz = rx.dot(ry).dot(rz)

Now I apply the rotation, with R and rxyz:

p1 = R.dot(v1t)
p2 = R.dot(v2t)
p3 = R.dot(v3t)

p4 = rxyz.dot(v1t)
p5 = rxyz.dot(v2t)
p6 = rxyz.dot(v3t)

The result is now better than the first approach and the Y of p1 and p3 are the correctly same, but p2 is still wrong. And there still seems to be a distortion.

P1-3 (red)

  1. [-0.20673470096224283, 1.1102230246251565e-16, -1.2299659828522118]
  2. [-0.5865305980755144, -3.885780586188048e-16, 0.45993196570442385]
  3. [0.7932652990377571, 1.1102230246251565e-16, 0.770034017147788]

P4-6 (blue)

  1. [-1.1482080390363765, 0.30059830961195716, -0.38316381732390803]
  2. [0.3040075530555323, -0.6336677067539932, -0.2481938771563051]
  3. [0.8442004859808443, 0.3330693971420361, 0.6313576944802128]

rotation result

The light gray triangle is the original translated to 0,0,0 and red and blue are the rotated ones.

phx16
  • 37
  • 5
  • 1
    `norm()` returns `res**0.5` which is correct; however you then square root this again before dividing: `tn = t / np.sqrt(n)`, which means `tn` is not correctly normalized. – meowgoesthedog Jul 22 '20 at 10:20
  • Tanks, it looks better but still distorted. I suspect the rotation matrix to be wrong, so I will calculate this by hand now and compare that. – phx16 Jul 22 '20 at 13:18
  • The separated rotation matrices code looks logically incorrect - it rotates the triangle by the *same* angle (normal-to-vertical) along all 3 axes. Maybe try a quaternion approach (easier to do than hard-coding the corresponding matrix). – meowgoesthedog Jul 22 '20 at 13:20
  • I've refactored the core calculations to basicly match the math in reference. I also corrected the mistake @meowgoesthedog found as well as the error of using `.multiply` on the matrix squaring (should be have been dot) and the `.dot` I used for multiplying vx2 with iv, where this seems to be in real `.multiply`. I will also look up the quaterion, but what bothers me is, that in reference post [1], this approach is accepted as working, while my implementation does not. – phx16 Jul 22 '20 at 18:22
  • P1-3 have very small Y-components (`~ 10^-16`), so the red triangle is parallel to the horizontal plane (to within floating point error, and assuming **Y = vertical** of course). I also checked the distances between the vertices and they are identical to those of the original triangle (again within error): `||v2 - v1|| = sqrt(3), ||v3 - v1|| = sqrt(5), ||v3 - v2|| = sqrt(2)`, which means they are congruent. Therefore the single matrix method (Rodrigues formula) is working correctly. As I mentioned before, disregard P4-6 as the multi-rotation method is logically incorrect. – meowgoesthedog Jul 23 '20 at 12:09
  • You are right. I was so fixed on the shape in the visualization to not realize the original triangle has a 90° angle. I also missed out the ^-16 somehow. So the errors in the original post where the additional sqrt as well as the switched dot and multiplication. Thanks again and sorry for bothering. – phx16 Jul 28 '20 at 14:31

0 Answers0