如何使数据点拟合主曲线随机变化的曲线?
How to make data points fit a curve with random variation from main curve?
所以基本上,假设你的曲线像 y = log(x)
。
const y = x => Math.log(x)
console.log(generate(10))
// [0, 0.6931471805599453, 1.0986122886681096, 1.3862943611198906, 1.6094379124341003, 1.791759469228055, 1.9459101490553132, 2.0794415416798357, 2.1972245773362196]
function generate(max) {
let i = 1
let ypoints = []
while (i < max) {
ypoints.push(y(i++))
}
return ypoints
}
现在有了这些点,我们也想以随机量偏离它们,这也遵循某种变化或随机偏离多少的曲线。因此,例如,随着曲线向上和向右变平,y
略微向上或略微向下移动,随着 y
远离 log(x)
标记的可能性降低。所以假设在 1/x
.
处逐渐消失
这意味着,它更有可能直接在 log(x)
上或靠近它,而不是远离它。但是我们可以用任何类似的方程交换。
如何让一个简单的 JavaScript 函数为您提供最终坐标集 (x, y)
,一个包含 x 和 y 坐标的二元组数组?我的尝试没有正确描述我一直试图描述的“根据次级曲线的变分衰减”。
// calling `u` the thing that converts x into a y point.
const u = x => Math.log(x)
// here, `v` is the equation for variation from the main curve, given a y.
const v = y => 1 / y
// `r` is the random variation generator
const r = y => y + (Math.random() * v(y))
const coordinates = generate(10, u, v, r)
console.log(coordinates)
function generate(max, u, v, r) {
let i = 1
let coordinates = []
while (i < max) {
const x = i++
const y = r(u(x))
coordinates.push([ x, y ])
}
return coordinates
}
如何取两条曲线并根据第二条曲线生成远离主曲线的随机变化probability/decay-rate?
预期的输出与评论中的第一个数组相差 +- 一些小量(如果我们沿 x 轴有 10 个点)。
// [0, 0.6931471805599453, 1.0986122886681096, 1.3862943611198906, 1.6094379124341003, 1.791759469228055, 1.9459101490553132, 2.0794415416798357, 2.1972245773362196]
所以它可能就像(只是编造这些,它们会更随机地确定):
// [0, 0.69, 1.1, 1.3, 1.43, 1.71, 1.93, 2, 2.21]
请注意它们更可能靠近 log(x)
曲线(因为 1/x
和随机性),而不是更远,它会变为 +-。
提问的主要原因(与这个抽象问题无关)是为了在开发过程中生成虚拟数据,以测试 UI 数据可视化功能,模拟看起来有些逼真的数据。我会为主曲线选择一个更复杂的方程,为变化选择一个类似的衰减方程,并可能生成数百万个点,所以这只是该问题的简化。
我说的是给定下一张图片中的曲线方程,生成随机点,这些点也像下一张图片中的点。
一种方法:
- 随机抽取一个
x
.
- 计算
y = f(x)
.
- 根据想要的分布获取此点的随机偏移量。
- Return这点.
const
f = x => 10 * Math.log(x),
offset = () => (1 / Math.random() - 1) * (Math.random() < 0.5 || -1),
canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
for (x = 0; x < 100; x++) {
const
y = f(x),
dx = offset(),
dy = offset();
console.log(x.toFixed(2), y.toFixed(2), dx.toFixed(2), dy.toFixed(2));
ctx.beginPath();
ctx.strokeStyle = '#000000';
ctx.arc(x * 4 , (100 - y) * 4, 0.5, 0, Math.PI * 2, true);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = '#ff0000';
ctx.arc((x + dx) * 4 , (100 - y + dy) * 4, 2, 0, Math.PI * 2, true);
ctx.stroke();
}
<canvas id="canvas" style="border-width: 0; display: block; padding: 0; margin: 0;" width="400" height="400"></canvas>
所以基本上,假设你的曲线像 y = log(x)
。
const y = x => Math.log(x)
console.log(generate(10))
// [0, 0.6931471805599453, 1.0986122886681096, 1.3862943611198906, 1.6094379124341003, 1.791759469228055, 1.9459101490553132, 2.0794415416798357, 2.1972245773362196]
function generate(max) {
let i = 1
let ypoints = []
while (i < max) {
ypoints.push(y(i++))
}
return ypoints
}
现在有了这些点,我们也想以随机量偏离它们,这也遵循某种变化或随机偏离多少的曲线。因此,例如,随着曲线向上和向右变平,y
略微向上或略微向下移动,随着 y
远离 log(x)
标记的可能性降低。所以假设在 1/x
.
这意味着,它更有可能直接在 log(x)
上或靠近它,而不是远离它。但是我们可以用任何类似的方程交换。
如何让一个简单的 JavaScript 函数为您提供最终坐标集 (x, y)
,一个包含 x 和 y 坐标的二元组数组?我的尝试没有正确描述我一直试图描述的“根据次级曲线的变分衰减”。
// calling `u` the thing that converts x into a y point.
const u = x => Math.log(x)
// here, `v` is the equation for variation from the main curve, given a y.
const v = y => 1 / y
// `r` is the random variation generator
const r = y => y + (Math.random() * v(y))
const coordinates = generate(10, u, v, r)
console.log(coordinates)
function generate(max, u, v, r) {
let i = 1
let coordinates = []
while (i < max) {
const x = i++
const y = r(u(x))
coordinates.push([ x, y ])
}
return coordinates
}
如何取两条曲线并根据第二条曲线生成远离主曲线的随机变化probability/decay-rate?
预期的输出与评论中的第一个数组相差 +- 一些小量(如果我们沿 x 轴有 10 个点)。
// [0, 0.6931471805599453, 1.0986122886681096, 1.3862943611198906, 1.6094379124341003, 1.791759469228055, 1.9459101490553132, 2.0794415416798357, 2.1972245773362196]
所以它可能就像(只是编造这些,它们会更随机地确定):
// [0, 0.69, 1.1, 1.3, 1.43, 1.71, 1.93, 2, 2.21]
请注意它们更可能靠近 log(x)
曲线(因为 1/x
和随机性),而不是更远,它会变为 +-。
提问的主要原因(与这个抽象问题无关)是为了在开发过程中生成虚拟数据,以测试 UI 数据可视化功能,模拟看起来有些逼真的数据。我会为主曲线选择一个更复杂的方程,为变化选择一个类似的衰减方程,并可能生成数百万个点,所以这只是该问题的简化。
我说的是给定下一张图片中的曲线方程,生成随机点,这些点也像下一张图片中的点。
一种方法:
- 随机抽取一个
x
. - 计算
y = f(x)
. - 根据想要的分布获取此点的随机偏移量。
- Return这点.
const
f = x => 10 * Math.log(x),
offset = () => (1 / Math.random() - 1) * (Math.random() < 0.5 || -1),
canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
for (x = 0; x < 100; x++) {
const
y = f(x),
dx = offset(),
dy = offset();
console.log(x.toFixed(2), y.toFixed(2), dx.toFixed(2), dy.toFixed(2));
ctx.beginPath();
ctx.strokeStyle = '#000000';
ctx.arc(x * 4 , (100 - y) * 4, 0.5, 0, Math.PI * 2, true);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = '#ff0000';
ctx.arc((x + dx) * 4 , (100 - y + dy) * 4, 2, 0, Math.PI * 2, true);
ctx.stroke();
}
<canvas id="canvas" style="border-width: 0; display: block; padding: 0; margin: 0;" width="400" height="400"></canvas>