# Use AIS_Animation to create a rotation animation with angle greater than 180 degree

Hi everyone, I don’t know if you have any experience in creating animations using AIS_Animation.

When I used AIS_Animation to create a rotation animation, I specified a starting rotation angle of 0 degrees and a stop rotation angle of 360 degrees to AIS_Shape. The animation time set was 10s. As a result, the AIS_Shape did not rotate in 10s; if I set the starting rotation angle If it is greater than 180 degrees, AIS_Shape can rotate according to the expected rotation process.

I wonder if you can find a solution in occt?

Thank you all.

Hi w d,

try to replace your animation by four animations each rotating your model 90° in 2,5 sec and define the starting-time for each by using SetStartPts of AIS_AnimationObject

For the four rotations I use the following quaternion definitions:

``````gp_Quaternion r1(0.0, 0.0, 0.0, 1.0);
gp_Quaternion r2(0.0, 0.0, 0.707107, 0.707107);
gp_Quaternion r3(0.0, 0.0, 1.0, 6.12323e-17);
gp_Quaternion r4(0.0, 0.0, -0.707107, 0.707107);``````

hI,I want to achieve a animation of circle movement or arc movement,could you give me a C++ sample code?
Thanks
Jason

``````//=============================================================================
//function : update
//purpose  :
//=============================================================================
if (myObject.IsNull()) {
return;
}
gp_Trsf aTrsf;

gp_Trsf trsfMove;
if (myTranslatePath.IsNull()) {
gp_XYZ movexyz;
NCollection_Lerp<gp_XYZ> myLocLerp(gp_XYZ(myStatusStart.translateKeyFrame.mFloatMoveX,
myStatusStart.translateKeyFrame.mFloatMoveY,
myStatusStart.translateKeyFrame.mFloatMoveZ),
gp_XYZ(myStatusEnd.translateKeyFrame.mFloatMoveX,
myStatusEnd.translateKeyFrame.mFloatMoveY,
myStatusEnd.translateKeyFrame.mFloatMoveZ));
myLocLerp.Interpolate(theProgress.LocalNormalized, movexyz);
trsfMove.SetTranslationPart(movexyz);
} else {
Standard_Real translate;
NCollection_Lerp<Standard_Real> myTranslateLerp(0,myTranslatePathLength);
myTranslateLerp.Interpolate(theProgress.LocalNormalized, translate);
GCPnts_AbscissaPoint abscissaPoint(GAC,translate,GAC.FirstParameter());
trsfMove.SetTranslation(myCenterPnt, myTranslatePath->Value(abscissaPoint.Parameter()));
}

Standard_Real scale;
NCollection_Lerp<Standard_Real> myScaleLerp(myStatusStart.scaleKeyFrame.mFloatScaleX,
myStatusEnd.scaleKeyFrame.mFloatScaleX);
myScaleLerp.Interpolate(theProgress.LocalNormalized, scale);
gp_Trsf trsfScale;
trsfScale.SetScaleFactor(scale);

gp_Trsf trsfRotate;
if (myStatusEnd.rotateKeyFrame.mAnimationRotateType == ANIMATION_ROTATE_TYPE_Direction) {
gp_Trsf starttrsf_rotate;
gp_Trsf starttrsf_rotateX;
gp_Trsf starttrsf_rotateY;
gp_Trsf starttrsf_rotateZ;
starttrsf_rotateX.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecx)),
starttrsf_rotateY.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecy)),
starttrsf_rotateZ.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecz)),
starttrsf_rotate = starttrsf_rotateX.Multiplied(starttrsf_rotateY).Multiplied(
starttrsf_rotateZ);

gp_Trsf endtrsf_rotate;
gp_Trsf endtrsf_rotateX;
gp_Trsf endtrsf_rotateY;
gp_Trsf endtrsf_rotateZ;
endtrsf_rotateX.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecx)),
endtrsf_rotateY.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecy)),
endtrsf_rotateZ.SetRotation(gp_Ax1(gpPntCenter, gp_Dir(gpVecz)),
endtrsf_rotate = endtrsf_rotateX.Multiplied(endtrsf_rotateY).Multiplied(endtrsf_rotateZ);

gp_QuaternionNLerp rotateLerp(starttrsf_rotate.GetRotation(), endtrsf_rotate.GetRotation());

Standard_Real anInner = starttrsf_rotate.GetRotation().Dot(endtrsf_rotate.GetRotation());
gp_Quaternion quaternion;
rotateLerp.Interpolate(theProgress.LocalNormalized, quaternion);

gp_Quaternion theResultQ = starttrsf_rotate.GetRotation() +
(endtrsf_rotate.GetRotation() - starttrsf_rotate.GetRotation())
* theProgress.LocalNormalized;

Standard_Real vl = Sqrt(quaternion.X() * quaternion.X() + quaternion.Y() * quaternion.Y() +
quaternion.Z() * quaternion.Z());
gp_Vec theAxis;
Standard_Real theAngle;
quaternion.GetVectorAndAngle(theAxis, theAngle);
gp_EulerSequence theOrder = gp_EulerSequence::gp_Extrinsic_XYZ;
Standard_Real theAlpha;
Standard_Real theBeta;
Standard_Real theGamma;
quaternion.GetEulerAngles(theOrder, theAlpha, theBeta, theGamma);
trsfRotate.SetRotation(gp_Ax1(myCenterPnt, theAxis), theAngle);

Standard_Real rotateanglex = myStatusStart.rotateKeyFrame.mFloatRotateX +
(myStatusEnd.rotateKeyFrame.mFloatRotateX -
myStatusStart.rotateKeyFrame.mFloatRotateX) *
theProgress.LocalNormalized;
Standard_Real rotateangley = myStatusStart.rotateKeyFrame.mFloatRotateY +
(myStatusEnd.rotateKeyFrame.mFloatRotateY -
myStatusStart.rotateKeyFrame.mFloatRotateY) *
theProgress.LocalNormalized;
Standard_Real rotateanglez = myStatusStart.rotateKeyFrame.mFloatRotateZ +
(myStatusEnd.rotateKeyFrame.mFloatRotateZ -
myStatusStart.rotateKeyFrame.mFloatRotateZ) *
theProgress.LocalNormalized;
gp_Trsf trsfrotatex;
gp_Trsf trsfrotatey;
gp_Trsf trsfrotatez;
trsfrotatex.Multiply(trsfrotatey);
trsfrotatex.Multiply(trsfrotatez);
trsfRotate = trsfrotatex;
} else if (myStatusEnd.rotateKeyFrame.mAnimationRotateType == ANIMATION_ROTATE_TYPE_Target) {
gp_Pnt center = myCenterPnt.Transformed(trsfMove);
gp_Dir dir(gp_Vec(center, myTargetPnt));
gp_Quaternion quaternion;
quaternion.SetRotation(gp::DX(), dir);
gp_Vec theAxis;
Standard_Real theAngle;
quaternion.GetVectorAndAngle(theAxis, theAngle);
trsfRotate.SetRotation(gp_Ax1(myCenterPnt, theAxis), theAngle);
} else {
gp_Trsf starttrsf_rotate;
starttrsf_rotate.SetRotation(gp_Ax1(maxisLin.Location(), maxisLin.Direction()),
myStatusStart.rotateKeyFrame.mFloatRotateAxis *
gp_Trsf endtrsf_rotate;
endtrsf_rotate.SetRotation(gp_Ax1(maxisLin.Location(), maxisLin.Direction()),

gp_QuaternionNLerp rotateLerp(starttrsf_rotate.GetRotation(), endtrsf_rotate.GetRotation());

gp_Quaternion quaternion;
rotateLerp.Interpolate(theProgress.LocalNormalized, quaternion);
gp_Vec theAxis;
Standard_Real theAngle;
quaternion.GetVectorAndAngle(theAxis, theAngle);
trsfRotate.SetRotation(gp_Ax1(maxisLin.Location(), maxisLin.Direction()), theAngle);

Standard_Real rotateangle = myStatusStart.rotateKeyFrame.mFloatRotateAxis +
(myStatusEnd.rotateKeyFrame.mFloatRotateAxis -
myStatusStart.rotateKeyFrame.mFloatRotateAxis) *
theProgress.LocalNormalized;
trsfRotate.SetRotation(gp_Ax1(maxisLin.Location(), maxisLin.Direction()),
}

aTrsf.PreMultiply(trsfScale);
aTrsf.PreMultiply(trsfRotate);
aTrsf.PreMultiply(trsfMove);

if (!myContext.IsNull()) {
myContext->SetLocation(myObject, aTrsf);
invalidateViewer();
} else {
myObject->SetLocalTransformation(aTrsf);
}
}``````

The first thing to do is to clarify the implementation logic of AIS's animation function.

The principle of rotating around a certain center point is to move and rotate at the same time.

Therefore, it is necessary to calculate the translation transformation and the rotation transformation.