George Reith
George Reith

Reputation: 13476

AS3: Find distance of rotation

I am rotating an object with TweenLite, however instead of a set duration I want the duration to be based upon the distance of rotation where 180 degrees = 3 seconds 90 = 1.5 and so on.

Here is my attempt to find the distance of rotation:

var time:Number = Math.abs(Math.atan2(Math.sin(angle-wheelObj.rotation),Math.cos(angle-wheelObj.rotation)); 
TweenLite.to(wheelObj, time, {shortRotation:{rotation:angle}, ease:Expo.easeOut, onComplete:rotateWheel, onCompleteParams:[target]});
TweenLite.to(carObj, time, {shortRotation:{rotation:angle}, ease:Expo.easeOut});

This just isn't working, time is sometimes huge when the rotation is small and sometimes tiny when it is big, so does anyone know a better way to do this?

Notes:

angle = target rotation

wheelObj.rotation = current rotation.

Upvotes: 0

Views: 1414

Answers (3)

almightyon
almightyon

Reputation: 1

I may be wrong (I've not used this library), but it seems you are overcomplicating this. You should just do:

θ=W*t

Where you W is:

W=2*pi/6

So you have:

θ=pi*t/3 (rads) or
θ=60*t (degrees)

Revision: For the shortest angle,

t= |θ| / 60 for θ < 180
t= ( 180 - |θ| ) / 60 for θ > 180

Or in your case:

var speed:Number = 60;
var angle:Number = Math.abs(angle - wheelObj.rotation) % 360;
if (angle > 180 ) {
     angle = 180 - angle;
}
var time:Number = Math.abs(angle)/speed;

Upvotes: 0

George Reith
George Reith

Reputation: 13476

The solution if anyone is interested:

var rotationSpeed:Number = 60;
var startAngle:Number = (angle < 0) ? (angle + 360) % 360:angle % 360;
var endAngle:Number = (wheelObj.rotation < 0) ? (wheelObj.rotation + 360) % 360:wheelObj.rotation % 360;
var distance:Number = (Math.max(startAngle,endAngle) - Math.min(startAngle,endAngle) > (360 + Math.min(startAngle,endAngle))- Math.max(startAngle,endAngle)) ? (360 + Math.min(startAngle,endAngle))- Math.max(startAngle,endAngle) : Math.max(startAngle,endAngle) - Math.min(startAngle,endAngle);
var time:Number = distance / rotationSpeed;
TweenLite.to(wheelObj, time, {shortRotation:{rotation:angle}, ease:Expo.easeOut, onComplete:rotateWheel, onCompleteParams:[target]});
TweenLite.to(carObj, time, {shortRotation:{rotation:angle}, ease:Expo.easeOut});

The following algorithm:

var distance:Number = (Math.max(startAngle,endAngle) - Math.min(startAngle,endAngle) > (360 + Math.min(startAngle,endAngle))- Math.max(startAngle,endAngle)) ? (360 + Math.min(startAngle,endAngle))- Math.max(startAngle,endAngle) : Math.max(startAngle,endAngle) - Math.min(startAngle,endAngle);

Compares the largest angle - the smallest angle to the smallest angle + 360 minus the largest angle and sees which one is bigger and sets itself as the answer. e.g,

20 and 320

320 - 20 = 300 (20 + 360) - 320 = 40

this works for any two angles (between 0 and 360) and always finds the shortest route.

Upvotes: 0

ymutlu
ymutlu

Reputation: 6715

var speed:Number = 60; // 3 sec for 180 deg
var time:Number = Math.abs(angle - wheelObj.rotation) / speed;

You can set duration by changing speed parameter.

Note: You might need to use angle as (angle%360)

Upvotes: 1

Related Questions