Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 低通罗盘平滑怪异_Javascript - Fatal编程技术网

Javascript 低通罗盘平滑怪异

Javascript 低通罗盘平滑怪异,javascript,Javascript,我正在尝试为指南针方位输入实现一个低通滤波器,我已经组合了一个基本函数,如下所示: var smoothing = 0.15; function lowPass(degree) { var oldVal = $scope.compassBearing || 0; var smoothedValue = oldVal + smoothing * (degree - oldVal); return smoothedValue; } 除了指南针方位向北(即从0到359突然改

我正在尝试为指南针方位输入实现一个低通滤波器,我已经组合了一个基本函数,如下所示:

var smoothing = 0.15;

function lowPass(degree) {
    var oldVal = $scope.compassBearing || 0;
    var smoothedValue = oldVal + smoothing * (degree - oldVal);
    return smoothedValue;
}
除了指南针方位向北(即从0到359突然改变,或反之亦然)时,工作正常


有没有人遇到过类似的问题,如果是,是如何解决的?

假设您总是希望它在最短路径上平滑。因此,如果变化是从270度到5度,它会经过north,那么您必须检查这些值,看看它们之间的差异是否超过180度。如果是,请稍微修改一下函数

如果差值小于-180,则翻转几个运算符并将360添加到混合中。如果差值大于180,情况也是如此。最后检查结果是否大于360或小于0,并进行更正

function lowPass(degree) {
    var oldVal = $scope.compassBearing || 0;
    var smoothedValue;

    if(oldVal - degree < -180){
        // Invert the logic
      smoothedValue = oldVal - smoothing * (oldVal + 360 - degree);
      if (smoothedValue < 0){
        smoothedValue = smoothedValue + 360;
      }
    } else if (oldVal - degree > 180){
        smoothedValue = oldVal + (360 + degree - oldVal) * smoothing;
      if (smoothedValue > 360){
        smoothedValue = smoothedValue - 360;
      }
    }
    else {
      smoothedValue = oldVal + smoothing * (degree - oldVal);
    }   
    return smoothedValue;
}
功能低通(度){
var oldVal=$scope.compassBearing | | 0;
var平滑值;
如果(旧值-度<-180){
//颠倒逻辑
平滑值=oldVal-平滑*(oldVal+360度);
if(平滑值<0){
平滑值=平滑值+360;
}
}否则,如果(旧值-度数>180){
平滑值=oldVal+(360+度-oldVal)*平滑;
如果(平滑值>360){
平滑值=平滑值-360;
}
}
否则{
平滑值=oldVal+平滑*(度-oldVal);
}   
返回平滑值;
}

它看起来很乱,但我只是随便玩了玩。希望这是你需要的。

如果你利用复杂的数学,有一种更优雅的方法可以做到这一点。基本上,用复数你可以表示指南针上的一个点

如果你想“平均”或“平滑”两个罗盘读数,你可以在复数域中这样做,然后转换回角度域

有了它,我们可以使用math js库,让函数基本上保持与您相同的形式:

var smoothing = .9;


function lowPass(degree, oldVal) {
    // var oldVal = $scope.compassBearing || 0;
    var complexOldVal = math.complex({r:1, phi:oldVal * (math.pi/180)});
    var complexNewVal = math.complex({r:1, phi:degree * (math.pi/180)});    
    var complexSmoothedValue = math.chain(complexNewVal)
                                   .subtract(complexOldVal)
                                   .multiply(smoothing)
                                   .add(complexOldVal)
                                   .done();
    var smoothedValue = math.arg(complexSmoothedValue) * (180/math.pi);
    if (smoothedValue < 0) { return 360 + smoothedValue; }
    return smoothedValue;
}

document.write(lowPass(20, 30)+'<br>');
// 20.99634415156203
document.write(lowPass(10, 350)+'<br>');
// 8.029256754215519
var平滑=.9;
函数低通(度数,oldVal){
//var oldVal=$scope.compassBearing | | 0;
var complexOldVal=math.complex({r:1,phi:oldVal*(math.pi/180)});
var complexNewVal=math.complex({r:1,phi:degree*(math.pi/180)});
var complexSmoothedValue=math.chain(complexNewVal)
.减去(complexOldVal)
.乘法(平滑)
.add(complexOldVal)
.完成();
var平滑值=math.arg(complexSmoothedValue)*(180/math.pi);
如果(SmoothdValue<0){return 360+SmoothdValue;}
返回平滑值;
}
写(低通(20,30)+'
'); // 20.99634415156203 写(低通(10350)+“
”; // 8.029256754215519

你可以在这里摆弄它:

问题出在哪里?
smoothValue
变成例如361,-2等?这是平滑试图将读数“平滑”到另一侧-因此,它不是平滑从356->358->0->2过渡,而是尝试平均这两个值,以便罗盘在相反方向快速旋转适应新价值观的方向。是的,我想到了。我自己刚试过你的剧本,看到了你真正的问题。从359到10的转变是“倒退的”,不是通过0。这个问题还不清楚。@SharkAlley用trig来解决这个问题,真是太棒了。我只是想挑逗一下,但你赢了我。周日的宿醉会让我的逻辑思维变得迟钝:)我必须承认,我真的可以用这个解决方案来解决我的问题。但对于这个简单的应用程序,我认为引入一个外部库,并疏远那些不熟悉弧度的人的代码,可能有点过分了。尽管如此,我还是很喜欢:)我听到了你的话,并且大体上同意。。。这种方法的一个优点是,如果您想进行更高级的平滑,它可以轻松地进行缩放。除了在角度域中求平均值之外,做任何事情都可能导致不期望的结果。在所有方面达成一致:P选择了danny,并纯粹为了可读性而实现了它。这个解决方案看起来很优雅,但对我来说,它本质上是一个黑匣子!