转盘旋转算法

86 篇文章 0 订阅
48 篇文章 0 订阅

今天应公司要求,实现一个转盘旋转算法,

         网上找了很多资料,再根据实际效果构造出了一个算法,其实原理很简单,下面我就来做一下总结:希望对遇到此类问题的朋友有所帮助或启发。

 

首先:转盘旋转分几个阶段:加速,减速,停止到指定位置。

       当然旋转当然与角度与弧度有关,弧度在这里我就不介绍了,当然是用旋转角度来转换的,公式为:角度/180 * PI

       一开始我对于加速过程与减速过程想了很多办法,结果没一种接近现实效果的。但是做这么多实验当然也不是徒劳的,从这些办法中我最终选择了正切函数曲线图(tan),

我将这个旋转过程分为两部分:加速,减速,我以原点坐标来表示加速到减速这个过度点,见下草图

 

从图中可以得出:

      当 Δx为常量时: Δy从-到0    减少, Δy从0到+    增加。(哈哈,正是我想要的结果,并且不是线性增加的,更接近真实性)

故:我决定以y代表时间,x代表角度。

//-------------------------------------------------------------------------------------------------------------

下面我开始编程实现:

定义变量:

doublem_dCurAngle;//当前的旋转角度

doublem_dTime;//距离旋转开始的时间

doublem_dCurveMid;//过度点时间(及前一段加速总时间)

c++中及得到算法函数(反正切函数):

            m_dCurAngle = atan((m_dTime - m_dCurveMid));

对,到此,雏形已经明了,现在就需要解决三个问题了:

       1、对于时间控制(我们淡然不是想y轴所对应的时间间隔相对于现实时间是一一对应的,说白了就是我们希望y轴的时间区块是可缩放的)

2、对于旋转到指定的点的问题还未解决的(随机出来的终点角度当然要是可控的)

         3、从上一次旋转结果开始运动,

下面我来解决这几个问题:

       对于第一个问题,非常简单,我们可以给时间设置一个时间参数(当然其实术语应该叫:曲线参数)

               我是将所有时间除以一个参数(如下定义):

    double m_dCurveParam;     //曲线参数(这里我设置为150)

    以上旋转就变成了:  m_dCurAngle = atan((m_dwRotateTime - m_dCurveMid) / m_dCurveParam);

对于第二个问题,解决办法很多:我这里说一个我自己实现的办法。

doublem_dRotateAngle;//旋转总角度(绝对角度)

 

doublem_dwRotateTime;//转盘旋转总时

doublem_dCurveScale;                                               //曲线量表

doublem_dCurveOffset;                                             //加速旋转总角度

我的解决办法依然是给设置个参数:

                     我们可以从上图中得到两段中共旋转角度:

                                 m_dCurveOffset = atan(- m_dCurveMid / m_dCurveParam);//前半段旋转角度负值

                             故能得到:

                                  m_dCurveScale=m_dRotateAngle / (atan((m_dwRotateTime - m_dCurveMid) / m_dCurveParam) - m_dCurveOffset);

                                其中:atan((m_dwRotateTime - m_dCurveMid) / m_dCurveParam) 表示后半段减速所旋转角度

故得出最后旋转算法:

                           m_dCurAngle = m_dCurveScale * ( atan((m_dTime - m_dCurveMid) / m_dCurveParam) - m_dCurveOffset);

这样:当旋转总时间结束后,就旋转到当前要旋转的点了,

 

下面做逻辑:

          if (m_dTime <= m_dwRotateTime)//旋转结束

{

m_dCurAngle = m_dCurveScale * (atan((m_dTime - m_dCurveMid) / m_dCurveParam) - m_dCurveOffset);

}

      else{

            //结束处理

              }

到此:第二个问题也被解决了:

下面来解决第三个问题:

       相信第二个问题解决了后,这个问题就简单到爆了。

              这个问题只需要改变两个地方:

1、改变旋转总角度(m_dRotateAngle

             如果你    m_dRotateAngle = 360.0 * Random(6)+ m_dRotateOffsetNow;  (m_dRotateOffsetNow表示此次相对于原点偏移)

          那么你需要改成:m_dRotateAngle = 360.0 * Random(6)+ (m_dRotateOffsetNow-m_dRotateOffsetPve);(m_dRotateOffsetPve表示上次相对于原点偏移

2、改变当前的旋转角度(m_dRotateAngle

             之前是这样  m_dRotateAngle = m_dRotateAngle;

           那么你要改成这样:m_dRotateAngle = m_dRotateAngle + m_dRotateOffsetPve;(m_dRotateOffsetPve表示上次相对于原点偏移

到此:全部旋转都解决(当然,此旋转为顺时针旋转,逆时针同理)

你不妨试试效果。

你可以调整前半段时间m_dCurveMid,跟曲线参数m_dCurveParam来实现自定义效果!

Good luck!!!

 

获取更多帮主请关注小程序

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值