典型的random walk并不关心方向变化。每次迭代都会产生一个新的方向。但是,如果您想象一个随机走动的动画点,它通常会跳来跳去。因此,目标是根据先前计算的点使曲线更平滑。
如何调整随机游走功能以使方向变化更平滑?
我的主要想法是拥有一种方法,该方法可以生成具有x和y坐标的新点,但是如果旋转(方向改变),则可以照看上一步并减小下一步(const radius
)的大小。 )接近180°。
因此,我正在使用 D3js 在x和y方向上随机采取新的步骤。最后,我将获得所有过去的步骤的数组,这些步骤受最大步骤数的限制。半径确定了平均步长应该在x和y轴上走多长时间。
const history = [];
const steps = 10;
const radius = 1;
let point = {
x: 0,
y: 0,
radians: null
};
for (let i = 0; i < steps; i++) {
console.log(point);
history.push(point);
const previousPoint = Object.assign({}, point);
point.x += radius * d3.randomNormal(0, 1)();
point.y += radius * d3.randomNormal(0, 1)();
point.radians = Math.atan2(
point.y - previousPoint.y,
point.x - previousPoint.x
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.js"></script>
答案 0 :(得分:1)
我决定不使用基于坐标的随机游动,而是随机为每次迭代生成一个新的弧度。因此,可以将新弧度和先前弧度相互比较,以决定新点将获得的速度。取决于这些弧度之间的最小范围,将设置速度。之后,必须先进行简单的正弦和余弦计算,才能生成新点的坐标。
至少我已经实现了最终目标:https://beta.observablehq.com/@nextlevelshit/gentlemans-random-walk-part-3
const steps = 10;
const stepSize = 10;
let point = {
x: 0,
y: 0,
radians: randomRadians(),
velocity: 0
};
for (let i = 0; i < steps; i++) {
console.log(point);
const radians = randomRadians();
const velocity = 1 - minimumDifference(radians, point.radians) / Math.PI;
point = {
// Coordinates calculated depending on random radians and velocity
x: Math.sin(radians * Math.PI) * stepSize * velocity + point.x,
y: Math.cos(radians * Math.PI) * stepSize * velocity + point.y,
radians: radians, // Randomly generated radians
velocity: velocity // Velocity in comparison to previous point
};
}
function randomRadians() {
return randomFloat(- Math.PI, Math.PI);
}
function randomFloat(min, max) {
return Math.random() * (max - min) + min;
}
function minimumDifference(x, y) {
return Math.min((2 * Math.PI) - Math.abs(x - y), Math.abs(x - y));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.8.0/d3.js"></script>