我想编写一个例子,其中小点具有根据它们移动的速度 – 而且还有一个随机运动叠加到“正确”运动.使用下面的处理代码,我得到以下动画:
正确的点应该是在右下角,我可以确定它的行为.问题是左点,这应该是“静态” – 所以它只会显示“随机”动作“到位”;然而,正如动画的.gif所示,它往往最终会偏离其原始位置一段距离.随机速度用下式计算:
this.randspeed.set(random(0,1)-0.5,random(0,1)-0.5);
我会猜到随机(0,1)-0.5不给我以“零”为中心的高斯状态“正态分布”;但是再说一次,即使是“适当的”高斯,我仍然可以有这样的“运气”,所以说正值[0:0.5]返回一整天,然后负值[-0.5:0)在第二天返回,最终还是一个正确的高斯.
所以,我想,我正在寻找一种方法来将(伪)随机序列(作为随机(0,1)-0.5生成的)序列转换为伪随机序列,但其中平均和的N个样本(例如10)是0.我不知道如何调用这个 – 随机序列周期性地收敛到零,我猜?
请注意,我一直在尝试下面直接改变位置;并且改变最终的保存位置 – 改变位置似乎更像是一个“自然的”平滑的运动(特别是模数运算,所以每个帧不分配新的随机速度);但是,它也允许随机噪声积累,并且将点“推”到其中心位置.此外,请注意,我花了几个时间,直到我可以在.gif上重现这一点,运行程序“活”似乎使得点从原来的位置更快地偏离(我已经阅读了关于硬件事件,磁盘写入用于在Linux上更改/ dev / random的熵,但我不知道是否相关).
此外,我想到在点位置周围设置一些虚拟边框,并且对边框中的随机运动进行碰撞检测,但是在我看来,这似乎是太多的工作(和矢量操作的cpu周期)这样的事情我本来希望随机函数可以以某种方式以更简单的方式“调和”.
那么,在有限的地区,中心位置的这种随机运动是否会有一个推荐的方法呢?
marbles.pde:
import java.util.*; // added for Iterator; ArrayList<Marble> marbles = new ArrayList<Marble>(); Iterator<Marble> imarb; color mclr = #0000FF; int RNDLIMIT = 2; int framecount = 0; void setup() { size(600,400,P2D); Marble m_moving = new Marble(width/2,height/2,2,2); marbles.add(m_moving); Marble m_stopped = new Marble(width/2-100,0); marbles.add(m_stopped); } void draw() { background(255); strokeWeight(1); stroke(mclr); fill(mclr); imarb = marbles.iterator(); while (imarb.hasNext()) { Marble m = imarb.next(); m.update(); ellipse(m.finalpos.x,m.finalpos.y,m.radius*2,m.radius*2); } framecount++; //~ saveFrame("marbles-######.png"); } class Marble { PVector position = new PVector(0,0); PVector finalpos = new PVector(0,0); PVector speed = new PVector(0,0); PVector randspeed = new PVector(0,0); float radius=4; public Marble() { } public Marble(float inx,float iny,float invx,float invy) { this.position.set(inx,iny); this.speed.set(invx,invy); } public void update() { this.position.add(this.speed); if (framecount % 4 == 0) { this.randspeed.set(random(0,1)-0.5); this.randspeed.setMag(RNDLIMIT); } int algoTry = 1; // 0 switch(algoTry) { case 0: this.finalpos.set(PVector.add(this.position,this.randspeed)); break; case 1: this.position.set(PVector.add(this.position,this.randspeed)); this.finalpos.set(this.position); break; } } }