Я не уверен, могу ли я правильно ответить на этот вопрос, но вот он идет.
Я хочу привести пример, где маленькие точки имеют скорость, по которой они перемещаются, - но также есть случайное движение, наложенное на "правильное" движение. Используя следующий код Processing
, я получаю следующую анимацию:
Правильная точка должна идти в нижний правый угол, и я в порядке с тем, как она ведет себя. Проблема заключается в левой точке, которая должна быть "статической", поэтому она будет показывать только "случайное" движение "на месте"; однако, как показывает анимационный .gif, он, как правило, отклоняется на некоторое расстояние от своего первоначального местоположения. Случайная скорость рассчитывается с помощью:
this.randspeed.set(random(0,1)-0.5, random(0,1)-0.5);
Я бы предположил, что random(0,1)-0.5
не дает мне гауссовское "нормальное распределение", сосредоточенное вокруг (или сходящееся к нулю); но опять же, даже если это был "правильный" гауссовский, я все равно мог бы иметь такую "удачу", чтобы, скажем, положительные значения [0: 0.5) возвращались на целый день, а затем отрицательные значения [-0.5: 0) возвращаются на следующий день, и, в конце концов, он все равно будет правильным гауссовым.
Итак, я думаю, я ищу способ конвертировать (псевдо?) - случайную последовательность (как созданную с помощью random(0,1)-0.5
) в псевдослучайную, но в которой средняя сумма N образцы (скажем, 10) равны 0. Я не уверен, как это назвать - случайная последовательность, периодически сходящаяся к нулю, я полагаю,
Обратите внимание, что я пытаюсь сделать это при изменении position
; и сохранение position
с изменением finalpos
вместо этого - изменение позиции кажется скорее "естественным", сглаженным движением (особенно при работе с модульным кадром, поэтому новая случайная скорость не присваивается каждому кадру); но затем он также позволяет накапливать случайный шум и "толкает" точку от своего центрального местоположения. Кроме того, обратите внимание, что мне потребовалось несколько упражнений, пока я не смог воспроизвести это на .gif, запуск программы "live", по-видимому, приводит к тому, что точка быстрее расходится с исходным местоположением (я читал что-то об аппаратных событиях, записи диска используются для изменения энтропии для /dev/random
в Linux, но я не знаю, связано ли это).
Кроме того, я думал о настройке какой-то виртуальной границы вокруг точки точки и обнаружении столкновения для случайного движения, выходящего из границы, - но мне кажется, что это слишком много работы (и циклы процессора для вектора операции) для такого рода вещей; Я бы надеялся, что случайная функция может быть как-то "закалена" проще.
Итак, был ли рекомендованный способ приблизиться к подобному случайному движению вокруг центрального местоположения в ограниченной области?
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, height/2, 0, 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, 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;
}
}
}