Notifications
Clear all

[Closed] Align an axis to a plane, using other axis?

 3ak

the problem was in side of rotation – rotate to the left or right? cause dot product gives only angle. So we need to add check with help of cross product – result will always point in direction according to right hand rule. So if crossprod of rotated axis and its projection = axis of rotation it means that we should rotate clockwise – so quat should be inverted… and vise versa.

tm1 = $Box001.transform
tm2 = $Plane001.transform

rotAxis = normalize tm1.row2
rotdAxis = normalize tm1.row1
axis3 = cross (normalize tm1.row2) (normalize tm2.row3)
rot = acos (dot rotdAxis (normalize axis3))
if rot>90 then rot-=180
rQuat = quat (rotAxis.x * (sin(rot / 2))) (rotAxis.y * (sin(rot / 2))) (rotAxis.z * (sin(rot / 2))) (cos (rot / 2))
if (normalize(cross rotdAxis axis3)) == rotAxis  then rQuat = inverse rQuat else rQuat
rotate $Box001  rQuat

Hope this will work in all cases=)

If I’m reading this right, the way it’s supposed to work is:

-rotAxis is the axis it is rotating around
-rotdAxis is the axis that is supposed to get aligned to the target plane,
-axis3 is the cross of the rotAxis and the target plane.

Let me know if I’m misinterpreting that. If I’m not, then it still isn’t working all the time. Trying all the permutations in my test scene, this is what’s happening:


-- This works
rotAxis = normalize tm1.row1
 rotdAxis = normalize tm1.row2
 axis3 = cross (rotAxis) (normalize tm2.row1)

-- This doesn't
rotAxis = normalize tm1.row1
  rotdAxis = normalize tm1.row2
  axis3 = cross (rotAxis) (normalize tm2.row2)

-- This works
 rotAxis = normalize tm1.row1
 rotdAxis = normalize tm1.row2
 axis3 = cross (rotAxis) (normalize tm2.row3)

-- This doesn't
rotAxis = normalize tm1.row1
   rotdAxis = normalize tm1.row3
   axis3 = cross (rotAxis) (normalize tm2.row1)
 
-- This doesn't
rotAxis = normalize tm1.row1
    rotDAxis = normalize tm1.row3
    axis3 = cross (rotAxis) (normalize tm2.row2)

-- This works
rotAxis = normalize tm1.row1
     rotdAxis = normalize tm1.row3
     axis3 = cross (rotAxis) (normalize tm2.row3)

-- This works
rotAxis = normalize tm1.row2
 rotdAxis = normalize tm1.row1
 axis3 = cross (rotAxis) (normalize tm2.row1)

-- This doesn't
 rotAxis = normalize tm1.row2
  rotdAxis = normalize tm1.row1
  axis3 = cross (rotAxis) (normalize tm2.row2)

-- This doesn't (but works if used a second time)
rotAxis = normalize tm1.row2
   rotdAxis = normalize tm1.row1
   axis3 = cross (rotAxis) (normalize tm2.row3)

-- This doesn't
rotAxis = normalize tml1.row2
rotdAxis = normalize tm1.row3
axis3 = cross (rotAxis) (normalize tm2.row1)

-- This doesn't
 rotAxis = normalize tm1.row2
 rotdAxis = normalize tm1.row3
 axis3 = cross (rotAxis) (normalize tm2.row2)

-- This works
  rotAxis = normalize tm1.row2
  rotdAxis = normalize tm1.row3
  axis3 = cross (rotAxis) (normalize tm2.row3)

-- This doesn't
  rotAxis = normalize tm1.row3
  rotdAxis = normalize tm1.row1
  axis3 = cross (rotAxis) (normalize tm2.row1)

-- This doesn't
   rotAxis = normalize tm1.row3
   rotdAxis = normalize tm1.row1
   axis3 = cross (rotAxis) (normalize tm2.row2)

-- This doesn't
    rotAxis = normalize tm1.row3
    rotdAxis = normalize tm1.row1
    axis3 = cross (rotAxis) (normalize tm2.row3)

-- This doesn't
     rotAxis = normalize tm1.row3
     rotdAxis = normalize tm1.row2
     axis3 = cross (rotAxis) (normalize tm2.row1)

-- This works
      rotAxis = normalize tm1.row3
      rotdAxis = normalize tm1.row2
      axis3 = cross (rotAxis) (normalize tm2.row2)

-- This works
       rotAxis = normalize tm1.row3
       rotdAxis = normalize tm1.row2
       axis3 = cross (rotAxis) (normalize tm2.row3)

 3ak

its interesting) could you please share your scene where it doesn’t work, and what rotations you’re after and i’ll try it.

 3ak

here is 105th version))


tm1 = $Box001.transform
tm2 = $Plane001.transform

rotAxis = normalize tm1.row2
rotdAxis = normalize tm1.row1
axis3 = cross (normalize tm1.row2) (normalize tm2.row3)
rot = acos (dot rotdAxis (normalize axis3))
if  rot>90 then abs (rot-=180)
rQuat = quat (rotAxis.x * (sin(rot / 2))) (rotAxis.y * (sin(rot / 2))) (rotAxis.z * (sin(rot / 2))) (cos (rot / 2))
if (normalize(cross rotdAxis axis3)) == rotAxis  then rquat = rquat else rquat = inverse rquat


rotate $Box001  rQuat
	

I think that actually made it worse… sorry

I don’t really have a specific scene I am testing this with, just making a box and a plane, and tilting the box off at random angles on x, y, and z…

 3ak

I don’t know why but:

so they are equal but last line return false. Even comparing them as strings returns true.

Hm, don’t know if this will help solve it or not, but I think with that last one, it might sometimes be rotating the right amount but in the wrong direction.

 3ak

i know – the main problem is to find which direction to choose)
one more problem is rounding in 3ds max – sometimes it differs in 0.00001 and my test fails)
so i added some range… I don’t like this approach. want to find more convenient way of checking side of rotation.

tm1 = $Box001.transform
tm2 = $Plane001.transform

rotAxis = normalize tm1.row3
rotdAxis = normalize tm1.row2
axis3 = cross (normalize rotAxis) (normalize tm2.row3)
rot = acos (dot rotdAxis (normalize axis3))
if  rot>90.0 then abs (rot-=180)
rQuat = quat (rotAxis.x * (sin(rot / 2))) (rotAxis.y * (sin(rot / 2))) (rotAxis.z * (sin(rot / 2))) (cos (rot / 2))
test = dot (normalize(cross rotdAxis axis3)) rotAxis 
if (test >0.9999) and (test<1.0001)  then rQuat = rQuat else rQuat = inverse rquat
rotate $Box001  rQuat

You are way better tester than me, so just ruin another attempt=)

That works for every single combination I tried! Thank you so much. I know it took a while longer to figure out than you expected it to, and I’m glad you stuck in there till you got it working

Incidentally, instead of using:

if (test >0.9999) and (test<1.0001)  then rQuat = rQuat else rQuat = inverse rquat

This seems a bit more succinct:

if abs(test - 1) > .0001 then rQuat = inverse rquat

And yes, rounding in Max can be a real pain. I’ve had to add tolerances to scripts on more than one occasion when they shouldn’t have been necessary.

Page 2 / 4