// Simulation of the sequence of events in a Poisson process // A rate of 0.1 per second would result in a mean time of 10 seconds between events float rate = 1; float t; float lastt; float last = 0; int xOffset; int yOffset; int targY; Line l; int rectH = 10; PFont fontA; int margin; int baseline; // Do some fading after an event int eventCounter=0; void setup(){ fontA = loadFont("Verdana-12.vlw"); textFont(fontA); margin = 40; baseline = 40; yOffset = 0; xOffset = 0; targY = 0; size(700,500); background(255); stroke(0); l = new Line(); t = findt(); frameRate(30); } void draw(){ int currentTime = millis(); background(255); xOffset = millis()/50; l.drawMovingBoxes(); //l.drawStaticBoxes(); if(eventCounter > 0){ eventCounter-=10; } // Is it time to fire an event? if((currentTime - last) > (t*1000)){ // Adding event in seconds l.addEvent(currentTime, t); last = currentTime; lastt = t; t = findt(); println("Now waiting " + t + " seconds before next event"); eventCounter = 100; } baseline = 40; fill(0); text("Expected rate: " + rate + " per second" , margin, baseline+=20); fill(eventCounter); text("Last wait: " + lastt + " seconds" , margin, baseline+=20); fill(0); if(currentTime>0){ float avg = simplify(l.getNumEvents() / ((float)currentTime/1000), 2); text("Actual rate per second: " + avg, margin, baseline+=20); } text("Total arrived: " + l.getNumEvents(), margin, baseline+=20); } float simplify(float input, int dp){ int tmp = (int)(input * (float)Math.pow(10,dp)); return (float)tmp/100; } float findt(){ return -1/rate * (float)Math.log(1 - Math.random()); } // the Line records the sequence of events class Line { Event[] events = new Event[9999]; int numEvents = 0; void addEvent(float when, float timeWaited){ Event e = new Event(when, timeWaited); //e.draw(); events[numEvents] = e; numEvents++; } int getNumEvents(){ return numEvents; } void drawStaticBoxes(){ stroke(0); for(int i=0; i0 ? events[i-1].getTime() : 0; int xVal = (int)(events[i].getTime()*3); int lastX = (int)(lastTime*3); int col = events[i].getCol(); fill(col/2, col, col); // draw a rectangle from the last time event to this rect(lastX, (height/2) - (rectH/4) - 40, xVal - lastX, rectH/2); } } void drawMovingBoxes(){ stroke(0); if(yOffset < targY){ yOffset++; } for(int i=0; i0 ? events[i-1].getTime() : 0; float scaler = 0.02; int xVal = (int)(thisTime*scaler) + (width-10) - xOffset; int lastX = (int)(lastTime*scaler) + (width-10) - xOffset; if(xVal > 0){ int col = events[i].getCol(); fill(col/2, col, col); // draw a rectangle from the last time event to this rect(lastX, height - (i * rectH) + yOffset, xVal - lastX, ((i+1)*rectH)); } if((i*rectH) - yOffset > 400){ targY = yOffset + rectH; } } } } class Event { float time; float timeWaited; int col; Event(float ct, float t){ time = ct; timeWaited = t; col = workOutColour(); } int getCol(){ return col; } int workOutColour(){ float c = (timeWaited/2)*255; return (int)c; } float getTime(){ return time; } }