javascript-使用对数缩放来计算线的细分
作者:互联网
我想计算一条具有totalLineLength长度的线的子段的长度,其中子段与给定事件的对数成正比.
视觉表示:| — | —– || ——— |由子段组成的线.
我希望计算的子段之和等于totalLineLength,并且必须打印成功.也必须使用Log(x 1)(因为对于正参数总是给出正的结果,并且也缩放1).
我正在使用线性缩放,并且可以正常工作.
var totalLineLength = 20;
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * x / eventTotal;
}
var events = [0.1, 1, 22];
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
var segmentLength = subSegments.reduce((a, b) => a + b);
if (segmentLength != totalLineLength) {
console.log("Error:", segmentLength);
} else {
console.log("Success");
}
使用log(x 1)(calcSubSegment已更新),它不起作用.
var totalLineLength = 20;
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * Math.log(x+1) / Math.log(eventTotal+1);
}
var events = [0.1, 1, 22];
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
var segmentLength = subSegments.reduce((a, b) => a + b, 0);
if (segmentLength != totalLineLength) {
console.log("Error:", segmentLength);
} else {
console.log("Success");
}
我的代码有什么问题?我猜想eventTotal的计算,但是我不确定如何进行.
我应该如何使用对数缩放?我也想要一个数学解释.
解决方法:
如果我正确理解您的任务,最简单的解决方案是首先使用log(x 1)函数映射所有事件,然后仅使用已经实现的线性拆分.像这样:
function linearSplit(events, totalLineLength) {
var eventTotal;
var calcSubSegment = function(x) {
return totalLineLength * x / eventTotal;
}
eventTotal = events.reduce((a, b) => a + b, 0);
var subSegments = events.map(calcSubSegment);
return subSegments;
}
function logSplit(events, totalLineLength) {
var logEvents = events.map(function(x) { return Math.log(x+1); } );
return linearSplit(logEvents, totalLineLength);
}
function testSplit(events, totalLineLength, fnSplit, splitName) {
var subSegments = fnSplit(events, totalLineLength);
var segmentLength = subSegments.reduce((a, b) => a + b, 0);
console.log(splitName + ":\n" + events + " =>\n" + subSegments);
if (Math.abs(segmentLength - totalLineLength) > 0.001) {
console.log(splitName + " Error:", segmentLength);
} else {
console.log(splitName + " Success");
}
}
var totalLineLength = 20;
var events = [0.1, 1, 22];
testSplit(events, totalLineLength, linearSplit, "linearSplit");
testSplit(events, totalLineLength, logSplit, "logSplit");
这个想法是唯一的分裂
>零件与某些系数成比例
>使所有部分的总和等于整体
同时是线性分裂.因此,如果要以任何方式缩放系数,则应在传递到线性拆分逻辑之前对其进行缩放.否则,部分总和将不等于代码中的整体(在任何非线性缩放的情况下).
附言用==比较浮点值不是一个好主意.您应该对计算/舍入误差使用一些容差.
标签:logarithm,javascript,math 来源: https://codeday.me/bug/20191110/2014915.html