开发者

Flash AS3: How to gradually limit rotation of an object influenced by y position of mouse

开发者 https://www.devze.com 2022-12-12 12:45 出处:网络
I have created a flash app in which there is a circle with circles plotted along it\'s circumference, it is rotated when the mouse is moved up or down. The rotation is drawn directly from the y positi

I have created a flash app in which there is a circle with circles plotted along it's circumference, it is rotated when the mouse is moved up or down. The rotation is drawn directly from the y position of the mouse pointer. What I would like to do is grade the movement开发者_如何转开发 some how so that the further down the mouse pointer goes the less impact on rotation the movement has.

My current code is like this:

myCircle.rotationZ = e.localY;

Is there some form of math formula I could use which would reduce the amount of rotation the greater the y position of the mouse position?

Thanks,

eb_dev


Well, it depends on how fast you want to decay the rotation angle. You can use simply use linear decay.

rot = ((Rmax - Rmin) / (Ymax - Ymin)) * y + ((Rmin * Ymax) - (Rmax * Ymin)) / (Ymax - Ymin)
Above expression will change the rotation angle 'rot' linearly from Rmax to Rmin depending on 'y' value from Ymax to Ymin. The same thing you can do using exponential decay.
Maths behind it:
rot = a * y + b //(where a,b are constants)
first boundary condition
Rmax = a * Ymax + b
second boundary condition
Rmin = a * Ymin + b
Solve above 2 equations to find out a and b.
a = (Rmax - Rmin) / (Ymax - Ymin)
b = ((Rmin * Ymax) - (Rmax * Ymin)) / (Ymax - Ymin) 


There are any number of ways to do what you want. Basically it sounds like you're trying to take the linear Y coordinate and turn it into a curve.

Something like this might do what you want (I'm a bit rusty at AS3 so it will need some tweaking but it should give you the idea - YMMV):

var distance:Number = (Stage.Height - e.localY) / Stage.Height;
distance = distance * distance;
myCircle.rotationZ = distance * 2 * 3.1415927;

It's converting the distance into a number from 0 to 1 where 0 is at the bottom and 1 is at the top.

Distance is then adjusted from a linear to parabolic curve.

Finally we convert the value from the range 0 - 1 to 0 to 2PI (the rotation angle).


bhups is right. Here is the Exponential version Please don't be scared by the name,read the comments and visit wikipedia for a visual representation :)

var scale:int=360;

var val:Number;

//From the exponential graph I chose the interval [-5,0]

//Consult http://en.wikipedia.org/wiki/Exponential_function , the image on the top-right

//corner for visual

/*For a value of 0 Math.exp returns 1;While going down to -5 it returns

values closer and closer to 0

*/

var intervalMaxValue:Number=0;

/* Warning! if you change the intervalMaxValue to something different than 0 you have to revise the formula */

var intervalLength:Number=5;

stage.addEventListener(Event.ENTER_FRAME,handlerEnterFrame);

function handlerEnterFrame(e:Event):void{

/* intervalMaxValue-intervalLength -> we start at -5

1-(stage.mouseY/stage.stageHeight)) * intervalLength -> and gradually add a number between 5 and 0 as the mouse goes down

Math.exp -> transforms it into something between 0 and 1 for this interval that ends with 0

scale -> Multiply it by scale to get the full 0-360 interval*/

val=Math.exp(intervalMaxValue-intervalLength+((1-(stage.mouseY/stage.stageHeight)) * intervalLength))*scale;

myCircle.rotation=val;

}


Flash AS3: How to gradually limit rotation of an object influenced by y position of mouse


(source: mathnstuff.com)

The above graph is from -4 to 4 on the x axis , it's easy to figure out the y value for x=-5 - it's almost 0 - so please consider this when reading the following.

Please see the above graph, it's the graph of the exponential function. See how it grows for x values from -5 to 0? It's not a linear growth but rather it's a bigger and bigger growth while it reaches 0. This is exactly what you need for your animation.

val=Math.exp(intervalMaxValue-intervalLength+((1-(stage.mouseY/stage.stageHeight)) * intervalLength))*scale;

intervalMaxValue-intervalLength is actually 0-5 which would be -5

So we start with -5!

Next

stage.mouseY/stage.stageHeight = 0 when your mouse is at the top of the stage(as stage.MouseY would be 0) and 1 when the mouse is at the Bottom of the stage ( stage.mouseY is then equal to stage.stageHeight so you divide stage.stageHeight by stage.stageHeight which will be 1)

For your effect you want it to be inverted, 1 when you are at the top and 0 when you are at the bottom so that's why you have to use (1-(stage.mouseY/stage.stageHeight))

Now when the mouse is at the top the above formula returns 1 and when it's at the bottom returns 0 ( exactly like you want it to behave , a big spin when it's at the top and a small one when it reaches the bottom )

Let's now take only the Math.exp part and see how it behaves

val=Math.exp(intervalMaxValue-intervalLength+((1-(stage.mouseY/stage.stageHeight)) * intervalLength);

When your mouse is at the TOP the above formula would be -5+((1-(0))*5(<-- 5 is here the intervalLength); this would return 0. Take a look at the graph now, for 0 on the x axis you get 1 on the y axis.

Now let's see what happens when the mouse is at the BOTTOM -5+(1-(1))*5; this would return -5. For -5 on the x axis you get something very close to 0 on the y axis as you can see in the image above.

Let's see what happens when the mouse is at the MIDDLE -5+(1-(0.5))*5; this would return -5+2.5 which would be -2.5.For -2.5 on the x axis you have something more closer to 0 on the y axis rather than on 1.This is what the exponential function does.

As you can see, on this interval [-5,0] the exponential function generates a y value from 0 to 1 and this value's growth is bigger as it approaches the x value of 0.

Considering that it generates a value from 0 to 1, that drops a lot while going to -5, you now multiply this value with 360 so you will get an angle value out of it.

At the TOP, the angle value is 1*360;

MIDDLE: the Math.exp for -2.5 returns a value somewhere near 0.1, multiply this by 360 and you get 36.If you compare it to the 360 for the TOP of the stage you observer that it sharply fell while the mouse reached the middle.

BOTTOM: Math.exp for -5 returns a value very close to 0. Multiply 0 with 360 and you get no angular movement. So when mouse is at the bottom of the stage the rotation value is extremely close to 0.

Hope this is clear, it was written at 6:53 AM, after a night out

Cheers.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号