简体   繁体   English

频率动态变化时,使振荡平滑增减

[英]Make oscillations smoothly increase/decrease when frequency being changed dynamically

I'm modeling the resonance effect with html5 canvas to animate spring when its reach the resonance.我正在使用 html5 画布对共振效果进行建模,以在弹簧达到共振时为其设置动画。 Also got jquery ui slider (max ranged) that changes frequency (w) of the oscillations dynamically during the animation.还获得了 jquery ui 滑块(最大范围),可在动画期间动态更改振荡的频率 (w)。 The problem is when its changed, for some reason sine wave brokes at some points and the animation is not smooth.问题是当它改变时,由于某种原因正弦波在某些点中断并且动画不流畅。 This is only happens when changing frequency, with amplitude its much better.这仅在改变频率时发生,幅度更好。 my main function to render each frame is this:我渲染每一帧的主要功能是这样的:

function doSways() {
var spring = springs[0],
        a = 0,
        A = params.standParams.A,
        w = params.standParams.w;

animIntervalId = setInterval(function() {
    ctx.clearRect(0, 0, cnvW, cnvH);
    A = params.standParams.A;       
    w = params.standParams.w;                       

    /*if (w < params.standParams.w) { // with this expression and commented <w = params.standParams.w> it works a bit smoother but still some issues can be noticed, for example sharp increases just after the new change of the frequency (w) on the slider
        w += 0.01;
    }*/

    stand.y = A*Math.sin(a*degToRad*w) + offsetY;       

    stand.draw();
    spring.draw(stand.y, A, w);

    if (a++ >= 360) {           //  avoid overflow
        a = 0;
    }
},
25);
}

here's how I change frequency(w) on the slider and assign it to params.standParams.w这是我如何更改滑块上的频率(w)并将其分配给 params.standParams.w

$( "#standfreq_slider" ).slider({
    range: "max",
    min: 1,
    max: 25,
    step: 1,
    value: 5,
    slide: function( event, ui ) {
      params.standParams.w = parseInt(ui.value);

    }
  });
 );

That if expression in doSways function kinda work but it casues another problem, I need to know the direction of sliding to determine wether I need to += or -= 0.01.. How to make everything work ideal ?如果 doSways 函数中的表达式有点工作,但它会导致另一个问题,我需要知道滑动的方向来确定我需要 += 或 -= 0.01 .. 如何使一切工作理想?

problem illustration live jsfiddle问题插图 live jsfiddle

based on the basic formula for sinusoids:基于正弦曲线的基本公式:

V = V0 + A * sin(2 * pi * f * t + phi)

Where:在哪里:

  • V: current value V:当前值
  • V0: center value V0:中心值
  • A: amplitude A:振幅
  • f: frequency (Hz) f:频率(赫兹)
  • t: time (seconds) t:时间(秒)
  • phi: phase phi:相位

We want the current value (V) to be the same before and after a frequency change.我们希望电流值 (V) 在频率变化前后保持相同。 In order to do that we will need a frequency (f) and phase (phi) before and after the change.为此,我们需要更改前后的频率 (f) 和相位 (phi)。

First we can set the first equation equal the the second one:首先,我们可以设置第一个等式等于第二个:

V0 + A * sin(2 * pi * f1 * t + phi1) = V0 + A * sin(2 * pi * f2 * t + phi2)

do some cancelling:做一些取消:

2 * pi * f1 * t + phi1 = 2 * pi * f2 * t + phi2

solve for the new phase for the final formula:求解最终公式的新相:

phi2 = 2 * pi * t * (f1 - f2) + phi1

More mathy version:更多数学版本:

最终公式

edited:编辑:

check out modified fiddle: https://jsfiddle.net/potterjm/qy1s8395/1/查看修改后的小提琴: https : //jsfiddle.net/potterjm/qy1s8395/1/

Well the pattern i explain below is one i use quite often.我在下面解释的模式是我经常使用的模式。
( It might very well have a name - please SO people let me know if so-. ) (它很可能有一个名字 - 如果是这样的话,请让人们告诉我。)

Here's the idea : whenever you need to want a property evolving in a smooth manner, you must distinguish the target value, and the current value.这里的想法是:每当你需要一个属性以平滑的方式演化时,你必须区分目标值当前值。 If, for some reason, the target value changes, it will only affect the current value in the way you decided.如果由于某种原因,目标值发生变化,它只会以您决定的方式影响当前值。

To get from the current value to the target value, you have many ways :要从当前值到目标值,您有很多方法:

• most simple : just get it closer from a given ratio on every tick : • 最简单:只需在每个刻度上从给定的比率接近:

current += ratio * (target-current); 

where ratio is in [0, 1], 0.1 might be ok.其中比率在 [0, 1] 中,0.1 可能没问题。 You see that, with ratio == 1, current == target on first tick.您会看到,第一次刻度上的比率 == 1,当前 == 目标。
Beware that this solution is frame-rate dependent, and that you might want to threshold the value to get the very same value at some point, expl :请注意,此解决方案取决于帧速率,并且您可能希望对该值设置阈值以在某些时候获得完全相同的值,expl:

var threshold = 0.01 ;
if (Math.abs(target-current)<threshold) current = target;

• You can also reach target at a given speed : • 您还可以以给定的速度到达目标:

var sign = (target - current) > 0 ? 1 : -1;
current  += sign * speedToReachTarget * dt;

Now we are not frame-rate dependent (you must handle frame time properly), but you will have 'bouncing' if you don't apply a min/max and a threshold also :现在我们不依赖于帧速率(您必须正确处理帧时间),但是如果您不应用最小值/最大值和阈值,则会出现“弹跳”:

if (Math.abs(target-current)<0.01) {
      current = target;
      return;
} 
var sign = (target - current) > 0 ? 1 : -1;
current  += sign * speedToReachTarget * dt;
current = (( sign > 0) ? Math.min : Math.max )( target, current);

• and you might use many other type of interpolation/easing. • 并且您可能会使用许多其他类型的插值/缓动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 动态增加和减少JavaScript中的数字 - Dynamically increase and decrease numbers in JavaScript jQuery使图像旋转间隔平滑减小 - jQuery Make image rotating interval decrease smoothly 动态增加和减少jQuery滑块值 - Dynamically increase and decrease jQuery slider values 动态增加和减少行高ng网格 - Dynamically increase and decrease row height ng grid 试图使变量在全局范围内动态更改 - Trying to make a variable that is being changed dynamically in a private scope global 如何在向下滚动时平滑地降低div的高度,并在向上滚动时以相同的速率增大它的高度? - How to smoothly decrease the height of a div on scroll down and increase it at the same rate on scroll up? 使用单选按钮动态增加/减少总价单 - Dynamically increase/decrease total price in order form that uses radio buttons 如何使div中的文本内容反复增加和减小字体大小? - How to make the text content in a div increase and decrease in font size repeatedly? 如何使sidenav增减高度,以始终填满整个网页 - How to make sidenav increase/decrease in height, to always fill the entire webpage 增加滚动时显示导航栏,减少滚动时隐藏导航栏 - Show Navbar when increase scroll, hide Navbar when decrease scroll
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM