Flash AS3:如何逐渐限制受鼠标 y 位置影响的对象旋转

发布于 2024-08-12 04:13:48 字数 270 浏览 6 评论 0原文

我创建了一个Flash应用程序,其中有一个圆圈,沿着它的圆周绘制了圆圈,当鼠标向上或向下移动时它会旋转。旋转直接从鼠标指针的 y 位置绘制。我想做的是对运动进行一定程度的分级,以便鼠标指针向下移动得越远,对运动旋转的影响就越小。

我当前的代码是这样的:

myCircle.rotationZ = e.localY;

是否可以使用某种形式的数学公式来减少鼠标位置的 y 位置越大的旋转量?

谢谢,

eb_dev

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

じ违心 2024-08-19 04:13:48

好吧,这取决于您想要以多快的速度衰减旋转角度。您可以简单地使用线性衰减。

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) 

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) 

拥抱影子 2024-08-19 04:13:48

有很多种方法可以做你想做的事。基本上,听起来您正在尝试获取线性 Y 坐标并将其转换为曲线。

像这样的东西可能会做你想要的(我对 AS3 有点生疏,所以它需要一些调整,但它应该给你这个想法 - YMMV):

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

它将距离转换为从 0 到 1 的数字,其中 0 位于底部,1 位于顶部。

然后距离从线性曲线调整为抛物线曲线。

最后我们将值从 0 - 1 范围转换为 0 到 2PI(旋转角度)。

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).

何以畏孤独 2024-08-19 04:13:48

bhups 是对的。这是指数版本
请不要被这个名字吓到,阅读评论并访问维基百科以获得直观的表示:)

var scale:int=360;

var val:数字;

//从指数图中我选择了区间[-5,0]

//查阅http://en .wikipedia.org/wiki/Exponential_function ,右上角的图像

//视觉效果

/*对于值为 0 Math.exp 返回 1;当下降到 -5 时,它返回的

值越来越接近为 0

*/

var IntervalMaxValue:Number=0;

/* 警告!如果将intervalMaxValue更改为不同于0的值,则必须修改公式
*/

var 间隔长度:数量=5;

stage.addEventListener(Event.ENTER_FRAME,handlerEnterFrame);

函数 handlerEnterFrame(e:Event):void{

/*
间隔最大值-间隔长度->我们从 -5

1-(stage.mouseY/stage.stageHeight)) * IntervalLength -> 开始并随着鼠标向下逐渐添加 5 到 0 之间的数字

Math.exp ->对于以 0 刻度结束的间隔,将其转换为 0 到 1 之间的值

->乘以scale即可得到完整的0-360间隔*/

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

myCircle.rotation=val;

}

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;

}

所谓喜欢 2024-08-19 04:13:48

替代文本
(来源:数学东西。 com)

上图的 x 轴从 -4 到 4,很容易算出 x=-5 的 y 值 - 它几乎为 0 - 所以请考虑这一点阅读以下内容。

请看上图,它是指数函数的图。看看 x 值从 -5 到 0 时它是如何增长的?它不是线性增长,而是在达到 0 时越来越大的增长。这正是您的动画所需要的。

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

IntervalMaxValue-intervalLength 实际上是 0-5,即 -5

所以我们从 -5 开始!

下一个

当鼠标位于舞台顶部时, stage.mouseY/stage.stageHeight = 0(因为 stage.MouseY 将为 0);当鼠标位于舞台底部时,stage.mouseY/stage.stageHeight = 1(此时 stage.mouseY 等于 stage) .stageHeight 所以你将 stage.stageHeight 除以 stage.stageHeight ,这将是 1)

对于你的效果,你希望它反转,当你在顶部时为 1,当你在底部时为 0,这就是你必须使用 ( 1-(stage.mouseY/stage.stageHeight))

现在,当鼠标位于顶部时,上述公式返回 1,当鼠标位于底部时,返回 0(与您希望的行为完全一样,当鼠标位于顶部时,会发生很大的旋转)当它到达底部时是一个小的)

现在让我们只使用 Math.exp 部分并看看它的行为

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

当你的鼠标位于顶部时,上面的公式将是 -5+((1-(0))*5( <-- 5 是这里的间隔长度);这将返回 0。现在看一下图表,对于 x 轴上的 0,您在 y 轴上得到 1

现在让我们看看当鼠标位于底部时会发生什么 。 -5+(1-(1))*5;这将返回-5。对于 x 轴上的 -5,您会在 y 轴上得到非常接近 0 的值,如上图所示。

让我们看看当鼠标位于中间时会发生什么 -5+(1-(0.5))*5;这将返回 -5+2.5,即 -2.5。对于 x 轴上的 -2.5,y 轴上的值更接近 0,而不是 1。这就是指数函数的作用。

正如你所看到的,在这个区间[-5,0]上,指数函数生成从0到1的y值,并且当它接近x值0时,该值的增长更大。

考虑到它生成从0到1的值,当变为 -5 时会下降很多,现在您可以将该值乘以 360,这样您就可以得到一个角度值。

在TOP处,角度值为1*360;

中间:-2.5 的 Math.exp 返回一个接近 0.1 的值,将其乘以 360,得到 36。如果将其与舞台顶部的 360 进行比较,您会发现当鼠标到达中间时,舞台急剧下降。

底部:-5 的 Math.exp 返回一个非常接近 0 的值。将 0 乘以 360,就不会得到角运动。因此,当鼠标位于舞台底部时,旋转值非常接近 0。

希望这一点很清楚,它是在上午 6:53 写的,经过一晚的

欢呼。

alt text
(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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文