[Closed] rotating TM in local space?
hey! i cant figure out how to rotate a transformation matrix in its local space… example:
--vector A or av = [0.339482,0.762032,0.551416]
av = (normalize ((lengthinterp $line01 1) - (lengthinterp $line01 0)))
m1 = matrixfromnormal av
cuboid = box length:2 width:2 height:6
--coordsys local rotate cuboid (eulerangles 30 0 0)
cuboid.transform = m1
i want to get the rotation as achieved by :
coordsys local rotate cuboid eulerangles (30 0 0)
but using m1, i tried this :
coordsys m1 rotate m1 (eulerangles 30 0 0)
but it returns in a TM rotated about the world space also resets the translation of the TM and the rotation axis about which it rotates is different from that of the local space of the cuboid
any help is appreciated thanks!
maths aaarghhh!
Hi, there is a couple of concept errors:
MatrixFromNormal is a Rotation Matrix because normal is considered to be in WorldSpace and sitting at the WorldOrigin. It means it has row4 == [0,0,0].
The other issue with MatrixFromNormal is that it computes one (among infinite) matrix which has Z axis oriented like the normal you feed the function with. It automatically uses as UpVector the World Z axis [0,0,1]. This explains why the rotation is not along the expected axis rotation.
If you want to rotate a matrix locally, use “preRotate” in place of “rotate”
coordsys m1 rotate m1 (eulerangles 30 0 0)
-- becomes:
coordsys m1 preRotate m1 (eulerangles 30 0 0)
Anyway the best way to do that, is to build a full Matrix by your own from first normal, then you can control the orientation of X and Y axis as well and not only Z.
Here is a function of mine to calculate a full matrix defined by a Ray (position and direction) and upVector:
function getMatrixFromRay &rPlane &p3UpVector theNodeTM:(Matrix3 1) fEpsi:1e-6
(
local p3Axis_Z = rPlane.dir
local p3Axis_X = cross p3UpVector p3Axis_Z
if ((length p3Axis_X) < fEpsi) then
p3Axis_X = normalize(cross theNodeTM.row2 p3Axis_Z)
else
p3Axis_X = normalize(p3Axis_X)
local p3Axis_Y = normalize(cross p3Axis_Z p3Axis_X)
return Matrix3 p3Axis_X p3Axis_Y p3Axis_Z rPlane.pos
)
- Enrico
thanks a lot for the detailed response . actually i was experimenting at the origin so i dint realize that the matrixfromnormal function was zeroing out the 4th row … so now i am using your function and the prerotate to setup and rotate the matrix about an arbitrary normal … also i just ran it on a plane with noise mod and placed cubes at each vert and they align perfectly with the normal and orient themself correctly as well since your function takes up vector as input…
(
function getMatrixFromRay &rPlane &p3UpVector theNodeTM:(Matrix3 1) fEpsi:1e-6 =
(
local p3Axis_Z = rPlane.dir
local p3Axis_X = cross p3UpVector p3Axis_Z
if ((length p3Axis_X) < fEpsi) then
p3Axis_X = normalize(cross theNodeTM.row2 p3Axis_Z)
else
p3Axis_X = normalize(p3Axis_X)
local p3Axis_Y = normalize(cross p3Axis_Z p3Axis_X)
return Matrix3 p3Axis_X p3Axis_Y p3Axis_Z rPlane.pos
)
my_mesh = $plane01.mesh
for vert = 1 to my_mesh.numverts do
(
my_box = box width:2 length:2 height:1 pos: (getvert my_mesh vert)
my_ray = ray (getvert my_mesh vert) (getnormal my_mesh vert)
up_vector = (getnormal my_mesh vert)
my_box.transform = getMatrixFromRay my_ray up_vector
)
)
and a snapshot:
thanks once again :bowdown: