Rotation Matrix problem
-
Hello, i've working with the ruby api for a few weeks now. I want to mate two components by their construction points (position) and Construction lines (alignment). I compute the global position of the points and move one component to another (so setting the position works fine). The problem is the alignment. I compoute the angle between the axis of the components. I get a correct angle in this part of my code. I also compue the normal vector of the plane that is defined by the two axes. Then i build a transformation matrix that should rotate the component , so the axes are parallel.The result is that they are "almost" parallel and the rotated component shrinks a little.
Can anyone tell me why this is working this way? Is the matrix correct? Thank you!This is my matrix (normal is the axis for the rotation, radAngle is the angle in radians:
trans = Array.new(16)
trans[0] = Math.cos(radAngle)+(normal[0]normal[0])(1-Math.cos(radAngle))
trans[1] = (normal[0]normal[1])(1-Math.cos(radAngle))+normal[2]*Math.sin(radAngle)
trans[2] = (normal[0]normal[2])(1-Math.cos(radAngle))-normal[1]*Math.sin(radAngle)
trans[3] = 0trans[4] = (normal[0]normal[1])(1-Math.cos(radAngle))-normal[2]*Math.sin(radAngle)
trans[5] = Math.cos(radAngle)+(normal[1]normal[1])(1-Math.cos(radAngle))
trans[6] = (normal[1]normal[2])(1-Math.cos(radAngle))+normal[0]*Math.sin(radAngle)
trans[7] = 0trans[8] = (normal[0]normal[2])(1-Math.cos(radAngle))+normal[1]*Math.sin(radAngle)
trans[9] = (normal[1]normal[2])(1-Math.cos(radAngle))-normal[0]*Math.sin(radAngle)
trans[10] = Math.cos(radAngle)+(normal[2]normal[2])(1-Math.cos(radAngle))
trans[11] = 0trans[12] = 0
trans[13] = 0
trans[14] = 0
trans[15] = 1mat = Geom::Transformation.new trans
$newComp.transform! mat
-
Rotation and Scaling are inexorably linked in a transformation - hence the weirdness...
Can I suggest another approach...
You are trying to align two objects they both have obj.transformation.axes and you can transform in steps...
Therefore you can move the objects together using
[tm=Geom::Transformation.translation(vector_from_point_to_point)
]
and then rotate one to align with
[tr=Geom::Transformation.rotation(point, axis, angle)
]- you can 'combine' transformations thus
t=tm*tr
and then use
obj.transform!(t)
in one step... but note that the 'order' is important in a matrix*
and the order of the transformations it will do is always taken as right-to-left... i.e. the move then the rotation - unlike normal numerical multiplication it's not commutative for matrices! Moving and then rotating will not necessarily give the same result as rotating and then moving - depending on the relativity of points etc...
PS: Put your code inside a [ code ]...[ /code ] block as it's easier to read.
You are using a $ variable - dangerous as it's exposed to all other tools and such a common name may well clash with other authors' unwrapped code too... Use @ or @@ variables that span methods within your own module/class only...
Parenthesize your arguments asmethod(1, 2, 3)
rather thanmethod 1, 2, 3
- although both work upcoming versions of Ruby may well deprecate unparenthesized arguments and even the most recent update caused some problems - I know th API guidance and many example scripts do it the 'wrong way' but it's a good habit to get now, before your code gets out of date unnecessarily... - you can 'combine' transformations thus
Advertisement