Translation + Rotation component to be side by side with another component


#1

Hello everyone,

I’m making a tool to put an element beside another, like image below:
Step 1:

Step 2:

Ok, everything works like a charm.

But when the component is rotated:

Both components remain like they had not been rotated.

What could be done?
I’m trying to do things with radian, sin and cos, but without success.

The steps are:
1 - Click on the element that will move
2 - Click on another component that will be the reference for the first one
3 - The first component moves to the side of the second.

Some code:

# @first = first element selected
# @f_origin = @first.transformation.origin
# same with @second and @s_*

vector = Geom::Vector3d.new [0, 0, 1]
rotation = Geom::Transformation.rotation @f_origin, vector, @s_rotz.degrees

trans = Geom::Transformation.translation [(@s_origin.x - @f_origin.x) - @f_lenx, @s_origin.y - @f_origin.y, 0]
@first.transform! trans * rotation

I’m trying now, something like this:

degree = @s_rotz
radian = degree * Math::PI / 180

amb_x = Math.cos(radian) * -@s_lenx
amb_y = Math.sin(radian) * @s_lenx
amb_z = 0
new_location = @s_origin + [ amb_x, amb_y, amb_z ]

axes_rotation = Geom::Transformation.axes new_location, @second.transformation.xaxis, @second.transformation.yaxis, @second.transformation.zaxis

@first.transform! axes_rotation

The rotation is ok, but the component moves to away from second component.

Thanks folks.


#2

Well, actually what it needs to do is rotate component, then translate it in x,y based in component’s axes, not global’s axes.

Is that possible?


#3

You can combine (“multiply”) a sequence of transformations to get on single transformations that does the same. But changing the order will not give the same result (not commutative). Like SketchUp uses nested components a lot, it also uses a lot of nested transformations. A component’s transformation describes how to convert a point from the component’s internal coordinate system to the outside coordinate system… and so on until it is finally in world coordinate system. The inverse of a transformation converts a point in world coordinates into a component’s interior coordinate system. (See more at Wikipedia…)

If you want a translation that is defined in terms of the “outer” coordinate system, you want to apply to it the inverse of the component’s transformation. This will give you the translation in terms of the component’s interior coordinate system.

translation_outside = Geom::Transformation.translation([x, y, 0])
translation_inside = component_instance.transformation.inverse * translation_outside

#4

I’m not quite sure if is that what I want.

Have tried to use Transformation#inverse but the component execute a translation about global’s origin. Very weird.

I need to move a component in x,y and z coordinates based on his own axis. If the componente is rotated 45º, then when move him in Y axis, he will move in diagonal from global axis and move straight based in component’s y axis.
Like this:


#5

Transformations, multiplication and inverse, that are the tools to solve such problems. Possibly the order of the transformations could be wrong (or the wrong one inversed).

If you just want to get the vector of an axis, why not use component_instance.transformation.yaxis?
(Note that it is not possible to reconstruct all properties that produced a transformation like angle, but it is always possible to get the axis, even if skewed/non-orthogonal.)


#6

Alright. I managed to do the first move.

The tool need to be able to align in any side and depth of the other component. Wether in front or behind or left or right or top or bottom.

In this example the user send an action to align at left side at the bottom (First move, left image). Then he wants to bring that same component to front (Second move, right image) and after that he wants to move back again, or move to other side to front and then move to bottom. In that moment I’m stuck, when need to work with translation with angles.

If the rot_z is 0, I just use:

def to_front
  trans = @first_element.transformation.translation[0, -(@s_leny - @f_leny), 0]
end

But with angle, I dont know how to do.

Yes, that’s the first move. Works perfect.

I think you mean “component_instance.transformation.yaxis” (typo).
But how I say to component move along his own yaxis?