I have a function s[x,y,z] that assumes a reference of centered at the origin and pointed along the positive z axis. Given two points, I want to rotate and translate that function such that its center is now at the midpoint of the two points and it is rotated to point toward the second of the points. I can do it sequentially with two operators like so:


However, I cannot seem to write an operator that does both correctly. This seems like it should work, and yet does not.

         RotationTransform[{Normalize[p1-p2],{0,0,1}}]][{x, y, z}])

The rotation seems fine, but the translation is off. Help?

Edited to add: Here is a test function and some initial points (midpoint at origin, displaced equally along z axis). enter image description here

Here is some code showing the starting conditions: enter image description here

Here is some code showing the desired outcome (the two points that will be passed, the vector for the direction I want it pointing, and the midpoint where I want the origin translated to). enter image description here

When I use the two individual operators in sequence, I get the correct output: enter image description here

But when I try to use the composite operator, I get this: enter image description here

  • $\begingroup$ does move[p1_, p2_]@ f_ := (Composition[f @@ TranslationTransform[-(p2 + p1)/2], f @@ RotationTransform[{Normalize[p1 - p2], {0, 0, 1}}]][{x, y, z}]) work? $\endgroup$
    – kglr
    Commented Nov 2, 2018 at 21:43
  • $\begingroup$ Doesn't seem to. In fact that version doesn't seem to operate on s at all. I am modifying my original post to include a test function. $\endgroup$ Commented Nov 2, 2018 at 21:59
  • $\begingroup$ move[point1, point2]@s gives s[1/2 (-point1 - point2)][ s[{(point1 - point2)/Norm[point1 - point2], {0, 0, 1}}][{x, y, z}]] $\endgroup$
    – kglr
    Commented Nov 2, 2018 at 22:01
  • $\begingroup$ Yes, and if I have a function defined for s and plug in actual values for the points, your version gives me: s[{{1., 0, 0, 0.6405}, {0, 1., 0, 0.6325}, {0, 0, 1., 1.796}, {0, 0, 0, 1.}}] s[{{0.910166, 0.0403062, -0.412279, 0.}, {0.0403062, 0.981916, 0.184979, 0.}, {0.412279, -0.184979, 0.892081, 0.}, {0., 0., 0., 1.}}][x, y, z]] $\endgroup$ Commented Nov 2, 2018 at 22:18
  • $\begingroup$ ah i see , thanks $\endgroup$
    – kglr
    Commented Nov 2, 2018 at 22:20

1 Answer 1


Ok, I have found a workaround, though I am still baffled by why a workaround is even needed. Here is what works:

move3[p1_, p2_]@f_ := Block[{tmp, pt}, 
       tmp = f @@ RotationTransform[{Normalize[p2 - p1], {0, 0, 1}}][{x, y, z}]; 
       pt = (p2 + p1)/2; 
       tmp /. {x -> x - pt[[1]], y -> y - pt[[2]], z -> z - pt[[3]]}]

The strange thing is that defining tmp as tmp[x_,y_,z_] and replacing the last line with tmp[x-pt[[1]],y-pt[[1]],z-pt[[1]]]] does not work!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.