gpt4 book ai didi

javascript - 给定最小值、最大值和平均值,我可以优雅地生成数据来拟合钟形曲线吗?

转载 作者:行者123 更新时间:2023-12-01 03:45:10 25 4
gpt4 key购买 nike

假设我有一个对象数组。

我有 3 个与该数组关联的值:最小高度、最大高度和平均高度。

我想为每个对象分配一个高度,以便:

  • 没有物体的高度小于 min-height
  • 没有物体的高度大于 max-height
  • 所有对象高度的平均值是average-height。

本质上我希望生成这样的高度分布:

enter image description here

高度必须是伪随机的 - 也就是说,我希望能够通过将随机数生成器的结果输入函数并获取返回的高度来获取每个对象的高度。

目前我的解决方案是将可接受的高度范围(全部在最小高度和最大高度之间)分成一系列容器,并为每个容器分配一个概率。选择垃圾箱后,我会从该范围内随机选择一个高度。

这不是一个理想的解决方案,因为它不优雅、笨重,并且会产生阶梯曲线而不是平滑曲线。

enter image description here

这是我当前用于生成垃圾箱的代码:

var min_height = 10
var max_height = 100
var avg_height = 30

var scale = SCALE ()
.map_from([min_height, avg_height, max_height])
.map_to([-Math.PI, 0, Math.PI])

var range = max_height - min_height;

var num_of_bins = 10
var bin_size = range/num_of_bins;

var bins = []
var sum_of_probability = 0

while (bins.length < num_of_bins) {
var bin = {};
bin.min = min_height + (bins.length*bin_size);
bin.max = bin.min + bin_size;
bin.mid = bin.min + (bin_size/2);

bin.probability = Math.cos(scale(bin.mid))+1
sum_of_probability += bin.probability;

bins.push(bin)
}

var i;
var l = bins.length;
for (i=0; i<l; i++) {
bins[i].probability /= sum_of_probability

if (bins[i-1]) {
bins[i].cumulative_probability = bins[i-1].cumulative_probability + bins[i].probability;
}
else {
bins[i].cumulative_probability = bins[i].probability;
}
}

本质上,我希望能够生成伪随机数据,以一种优雅的方式粗略地拟合曲线,并且我不确定这在 JavaScript 中是否可行。如果您认为这是可行的,请告诉我。

最佳答案

我从这里借用了高斯“类”:html5 draw gaussian function using bezierCurveTo .

真正与您相关的是getPoints() 函数。基本上,给定最小、最大和平均高度,getPoints() 将返回一个具有平滑高斯曲线值的数组。然后,您可以获取这些点并将它们缩放到您需要的任何范围(只需将它们相乘)。

generateValuesnumSteps 值(其中 getPoints 已硬编码为 1000)控制返回的值数量,为您提供更好的“分辨率”。如果您执行类似 10 的操作,您将获得类似于条形图的值。给定 1000 会给出一条漂亮的平滑曲线。

希望这有帮助。

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

canvas.width = 400;
canvas.height = 200;

var Gaussian = function(mean, std) {
this.mean = mean;
this.std = std;
this.a = 1/Math.sqrt(2*Math.PI);
};

Gaussian.prototype = {
addStd: function(v) {
this.std += v;
},

get: function(x) {
var f = this.a / this.std;
var p = -1/2;
var c = (x-this.mean)/this.std;
c *= c;
p *= c;
return f * Math.pow(Math.E, p);
},

generateValues: function(start, end, numSteps = 100) {
var LUT = [];
var step = (Math.abs(start)+Math.abs(end)) / numSteps;
for(var i=start; i<end; i+=step) {
LUT.push(this.get(i));
}
return LUT;
}
};

const getPoints = () => {
const minHeight = 0;
const maxHeight = 200;
const averageHeight = 50;

const start = -10;
const end = 10;
const mean = averageHeight / (maxHeight - minHeight) * (end - start) + start;
const std = 1;

const g = new Gaussian(mean, std);
return g.generateValues(start, end, 1000);
}

const draw = () => {
const points = getPoints();

// x-axis
ctx.moveTo(0, canvas.height - 20);
ctx.lineTo(canvas.width, canvas.height - 20);

// y-axis
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);

ctx.moveTo(0, canvas.height - 20);
console.log(points);
for (let i = 0; i < points.length; i++) {
ctx.lineTo(i * (canvas.width / points.length),
canvas.height - points[i] * canvas.height - 20);
}

ctx.stroke();
};

draw();
body {
background: #000;
}

canvas {
background: #FFF;
}
<canvas></canvas>

关于javascript - 给定最小值、最大值和平均值,我可以优雅地生成数据来拟合钟形曲线吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43615680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com