0
votes

I have an UserControl that needs to rotate and translate according to external infomration that I receive (X,Y and Angle in degrees) inside a canvas where I dinamically add usercontrols.

I use doubleanimations and a trasnformgroup to do it.

The problem I am experiencing is that when the objects needs to update its position from an angle > 0 to and angle < 360, for example rotating from 5° to 355°, the animation prefers the counterclockwise rotation instead to the clockwise, which I need.

this is a part of the code, where body is my UserControl added to the canvas:

var bodymove = new TranslateTransform();
var bodygrp = new TransformGroup();
bodygrp.Children.Add(bodyrot);
bodygrp.Children.Add(bodymove);
body.RenderTransform = bodygrp;


private void RotateBody(AgvStatus status, Duration duration, double newx, double newy)
{
    // correct bouncing around zero degrees
    if (-lastangle[status.Agv - 1] >= 0 && status.Angle < 360 && status.Angle > 355)
    {
        status.Angle = -lastangle[status.Agv - 1];
    }
    // Set and begin AGV bodyrot
    DoubleAnimation animrot = new DoubleAnimation(lastangle[status.Agv - 1], -status.Angle, duration); 
    bodyrot.BeginAnimation(RotateTransform.AngleProperty, animrot);
    lastangle[status.Agv - 1] = -status.Angle;
}

I managed to correct if I receive angles that bounces around zero, so the control stops rotating back and forward, for example if I receve 0 then 360 then 0 then 360 etc...

What I can't correct is if the object starts from a position greater than zero and goes to a posisition less that 360 (it is rotating clockwise), in the program it rotates counterclockwise.

I have no storyboard for this animation.

1
You can specify > 360 degrees to ensure rotation is clockwise. Then normalise after the animation, or at the start of the new one?GazTheDestroyer
@GazTheDestroyer thank you for your reply. Can you be a little more specific, I don't understand what you mean.Nedo2490
So if current rotation is 350° and you want to rotate to 10°, then you animate from 350-370, meaning the rotation will be clockwise. After the animation is finished, or when you start the next animation, you need to start from 10 rather than 370.GazTheDestroyer
@GazTheDestroyer thank you very very much, problem solved !!!!!!Nedo2490

1 Answers

0
votes

So, thanks to @GazTheDestroyer comment I managed solving the problem going above 360 if rotation has to be counterclockwise from angles <= 360, and going lower than 0 angles if rotation has to be clockwise with angles starting above 0 degrees:

private void RotateBody(AgvStatus status, Duration duration)
{
    // correct rotation if new angle received (status.Angle) is bouncing around 0/360 degrees
    var destAngle = 0d;
    var lastAngle = lastangle[status.Agv - 1];
    if (-lastAngle >= 0 && -lastAngle <= 2 && status.Angle > 358)
    {
        destAngle = 0;
    }
    else if (-lastAngle <= 360 && -lastAngle >= 358 && status.Angle > 0 && status.Angle < 2)
    {
        destAngle = 360;
    }
    else if (-lastAngle >= 0 && -lastAngle <= 15 && status.Angle <= 360 && status.Angle >= 340)
    {
        destAngle = 360 - status.Angle;
    }
    else if (-lastAngle <= 360 && -lastAngle >= 345 && status.Angle >= 0 && status.Angle <= 15)
    {
        destAngle = 360 + status.Angle;
    }
    else
    {
        destAngle = status.Angle;
    }

    var animrot = new DoubleAnimation(lastangle[status.Agv - 1], -destAngle, duration); // Set and begin AGV bodyrot
    bodyrot.BeginAnimation(RotateTransform.AngleProperty, animrot);
    lastangle[status.Agv - 1] = -status.Angle;
}