Rotating and translating a cylinder in 3D space.

Hi,

I want to rotate and translate a cylindric shape in 3D space.
. My input data for the rotation is a vector giving the direction of the cylinder's axis
. The translation is given by a point.

Here is my code to achieve this :

//Initialize an AIS_InteractiveContext and a V3d_View objects.
//...
gp_Dir axis (1, 1, 1);//the new orientation
gp_Pnt pos (50, 50, 0);//the new position

TopoDS_Shape cylinder = BRepPrimAPI_MakeCylinder (50, 100);//create the shape.
Handle_AIS_InteractiveObject cylinder_item = new AIS_Shape (cylinder);
ais_context->Display (cylinder_item, true);//display the cylinder

gp_Trsf trans;//Define the transformation
trans.SetValues (1, 0, axis.X (), pos.X (),
0, 1, axis.Y (), pos.Y (),
0, 0, axis.Z (), pos.Z (),
0.00001, 0.00001);
ais_context->SetLocation (cylinder_item, trans);//apply the transformation
ais_context->UpdateCurrentViewer ();

The orientation of the shape is ok, as well as the position, but the cylinder get deformed, the sections are not good.

Have someone already done this before?

Thanks.

Francois Lauzon's picture

Hi Hugues,
I have never done what you've done, instead I transform the TopoDS_Shape directly using BRepBuilderAPI_Transform, but maybe you don't want to do that...

Good Luck,
Francois.

Hugues's picture

Apparently there is no need to transform the underlying TopoDS_Shape object. Applying the gp_Trsf object to the AIS_Shape one, using SetLocation, works fine (the same is used in the MFC sample "Display Animation" coming with OCC 5.2).
So François, do you know the rotation matrix given the orientation(a vector) of the shape?

Thanks.

Valery Ovchinnikov's picture

Hi,
You can use SetRotation and SetTranslation:
trans.SetRotation (...);
gp_Trsf t;
t.SetTranslation(...)
trans *=t;

Hugues's picture

ok ok,

So with my team-mate (S. Lucet, special dedication to him) with have found a good solution (apparently it works well, and it's fast).

The problem with a rotation matrix A is that it must obey to two constraints(to represent an isometric transformation) :
det A = 1
A x tA = I
More informations on this here :
http://www.makegames.com/3drotation/

I'm giving here a rotation matrix that satisfy these conditions, but we believe it must only be used on a symmetrical object(like a cylinder).
So consider we have a vector V and a position P. What we want to do here is to locate a cylinder at position P with its axis along V.

Here is some pseudo-code that build the rotation matrix from V and P :

Real vx = V.x;
Real vy = V.y;
Real vz = V.z;

Real sx = 1;
Real nx = 0;
Real ny = 1;

if (vx != 0 or vy != 0)
{
Real alpha = (1 - vz) / (vx*vx + vy*vy);
sx = -vy*vy*alpha - vz;
nx = alpha*vx*vy;
ny = -vx*vx*alpha - vz;
}

gp_Trsf trans;
trans.SetValues (sx, nx, vx, P.x,
nx, ny, vy, P.y,
vx, vy, vz, P.z,
angular_precision, confusion_precision);
ais_context->SetLocation (shape_item, trans);//perform the transformation

Note : shape_item is an AIS_InteractiveObject instance owning a cylinder shape.

Albert Woo's picture

thanks