/**
* Random Walker
*
* This is an implementation of the Random Walker based on the example given in
* "The Nature of Code"
*/
// This is the div where the canvas will be placed
let nested_parent_div_id = "nested-follower";
/**
* The sketch creator
*
* @param {P5} p
*/
let nested_follower_sketch = function(p) {
/**
* Setup the canvas
*
* - Attaches the canvas to the div
* - Creates the walker objects
*/
p.setup = function() {
this.canvas = p.createCanvas($("#" + nested_parent_div_id).outerWidth(true), 800);
p.parent = new NoiseWalker(p);
let followers = 10;
p.followers = [new Follower(p, p.parent)];
for (let step=0; step < followers; step++) {
p.followers.push(new Follower(p, p.followers[step]));
};
};
/**
* Refresh the objects by calling their update functions
*
* This also clears the background.
*/
p.draw = function() {
p.background(255, 255, 255, 50);
p.parent.update();
p.followers.forEach(function(follower) {
follower.update();
});
};
};
/**
* The main walker (with perlin noise)
*
* @param {P5} p
*/
function NoiseWalker(p) {
// Our kinematics vectors
this.position = p.createVector(p.width/2, p.height/2);
this.velocity = p.createVector(0, 0);
this.acceleration = p.createVector(0, 0);
// Time for the perlin noise function
this.time_x = 0;
this.time_y = 10000;
this.time_delta = 0.01;
// The limit of how much we'll accelerate
this.max_acceleration = 0.05;
/**
* Updates the walker's position
*/
this.walk = function() {
// set the acceleration using perlin noise
this.acceleration.x = p.map(p.noise(this.time_x), 0, 1,
-this.max_acceleration,
this.max_acceleration);
this.acceleration.y = p.map(p.noise(this.time_y), 0, 1,
-this.max_acceleration,
this.max_acceleration);
// Move the walker
this.velocity = this.velocity.add(this.acceleration);
this.position = this.position.add(this.velocity);
// keep it within the window
if (this.position.x < 0)
this.velocity.x = p.abs(this.velocity.x);
else if (this.position.x > p.width)
this.velocity.x = -this.velocity.x;
if (this.position.y < 0)
this.velocity.y = p.abs(this.velocity.y);
else if (this.position.y > p.height)
this.velocity.y = -this.velocity.y;
// update the time
this.time_x += this.time_delta;
this.time_y += this.time_delta;
};
/**
* draws the walker (for debugging)
*/
this.display = function() {
p.stroke(0);
p.point(this.position.x, this.position.y);
};
/**
* Calls the walk function
*/
this.update = function() {
this.walk();
};
}
/**
* A follower that follows a parent object
*
* @param {P5} p
* @param {NoiseWalker} parent
*/
function Follower(p, parent) {
this.parent = parent;
this.variance = p.random(1, 10);
this.position = p.createVector(
this.parent.position.x + p.random(-this.variance, this.variance),
this.parent.position.y + p.random(-this.variance, this.variance));
this.velocity = p.createVector(0, 0);
// some colors to cycle through
this.max_diameter = p.round(p.random(5, 200));
this.time_x = p.random(100);
this.time_y = p.random(10000, 11000);
this.time_delta = 0.005;
/**
* Moves the Follower
*
* sets the acceleration by pointing to the parent's position
*/
this.walk = function() {
let acceleration = p5.Vector.sub(this.parent.position, this.position);
this.velocity = this.velocity.add(acceleration);
this.position = this.position.add(this.velocity);
};
/**
* Display the Follower
*
* cycles through the colors as we go
*/
this.display = function() {
// set our line width
p.strokeWeight(p.map(p.noise(this.time_x, this.time_y),
0, 1, this.variance, 2 * this.variance));
// set our color
p.stroke(63, 63, 191);
// don't fill the object
p.noFill();
// draw our object with a random diameter
p.ellipse(this.position.x, this.position.y,
p.round(p.random(5, this.max_diameter)),
p.round(p.random(5, this.max_diameter)));
// update the time
this.time_x += this.time_delta;
this.time_y += this.time_delta;
};
/**
* calls the update and walk
*/
this.update = function() {
this.walk();
this.display();
};
}
// create the p5 object and attach it to the div
new p5(nested_follower_sketch, nested_parent_div_id);
End
Beginning
Instead of a random walker this walker will be attracted (somewhat) to the mouse cursor.
Middle
let parent_div_id = "mouse-follower";
let mouse_follower_sketch = function(p) {
p.setup = function() {
this.canvas = p.createCanvas($("#" + parent_div_id).outerWidth(true), 800);
p.walker = new MouseWalker(p);
}
p.draw = function() {
p.background(255);
p.walker.walk();
p.walker.display();
}
};
function MouseWalker(p) {
this.position = p.createVector(p.width/2, p.height/2);
this.velocity = p.createVector(0, 0)
this.walk = function() {
mouse = p.createVector(p.mouseX, p.mouseY);
// calling sub on the vectors does an in-place update
// using p5.Vector.sub creates a new vector
// This is a static method so we use the module (p5) not the instance (p)
acceleration = mouse.sub(this.position);
// setMag always produces the same magnitude (but the orientation stays the same)
acceleration.setMag(0.1);
this.velocity = this.velocity.add(acceleration);
this.position = this.position.add(this.velocity)
}
this.display = function() {
p.stroke(0);
p.noFill();
p.background(255, 255, 255, 25);
p.ellipse(this.position.x, this.position.y, 48, 48);
}
}
sketch_container = new p5(mouse_follower_sketch, parent_div_id);
End
- Shiffman D. The nature of code: simulating natural systems with processing. Version 1.0, generated December 6, 2012. s.l.: Selbstverl.; 2012. 498 p.
Beginning
This is an extension of the random walker with acceleration added.
Middle
let random_accelerator_sketch = function(p) {
p.setup = function() {
let parent_div_id = "random-accelerator";
this.canvas = p.createCanvas($("#" + parent_div_id).outerWidth(true), 800);
this.canvas.parent(parent_div_id);
p.walker = new Walker(p);
}
p.draw = function() {
p.background(255);
p.walker.walk();
p.walker.display();
}
};
function Walker(p) {
this.position = p.createVector(p.width/2, p.height/2);
this.velocity = p.createVector(0, 0)
this.walk = function() {
acceleration = p.createVector(p.random(-1, 1), p.random(-1, 1));
acceleration = acceleration.mult(0.1)
this.velocity = this.velocity.add(acceleration)
this.position = this.position.add(this.velocity)
}
this.display = function() {
p.stroke(0);
p.noFill();
p.background(255, 255, 255, 25);
p.ellipse(this.position.x, this.position.y, 48, 48);
}
}
sketch_container = new p5(random_accelerator_sketch, 'random-accelerator');
End
This was a very rudimentary walker, the main point of it was that at this point we have the basic kinematic elements to make something following the rules of classical physics (more or less).
- Shiffman D. The nature of code: simulating natural systems with processing. Version 1.0, generated December 6, 2012. s.l.: Selbstverl.; 2012. 498 p.
Beginning
This is another post to see if I understand how to get p5.js working in nikola. It's been a while since I tried and I just want to see if I remember how. This uses the random walk example from Daniel Schiffman's book the Nature of Code.
Middle
A Div to Locate the Sketch
The id of this div is set in the p5.js
setup
function as the parent of the sketch.
<script language="javascript" type="text/javascript" src="walker.js"></script>
<div id="random-walk-container">
</div>
Note: Originally this wasn't working, because I had the line to include the javascript inside the div
to hold the canvas. Make sure that div
is always empty.
The Javascript
let sketch = function(p) {
p.setup = function() {
let parent_div_id = "random-walk-container";
this.canvas = p.createCanvas($("#" + parent_div_id).outerWidth(true), 300);
this.canvas.parent();
p.walker = new Walker(p);
}
p.draw = function() {
p.background(255);
p.walker.walk();
p.walker.display();
}
};
function Walker(p) {
this.x = p.width/2;
this.y = p.height/2;
this.walk = function() {
this.x = this.x + p.random(-1, 1) * 10;
this.y = this.y + p.random(-1, 1) * 10;
}
this.display = function() {
p.fill(0);
p.ellipse(this.x, this.y, 48, 48);
}
}
//let node = document.getElementById("random-walk")
//window.document.getElementsByTagName("body")[0].appendChild(node);
sketch_container = new p5(sketch, 'random-walk-container');
End
As always, this was way harder than it should have been.
I'm reading "The theory that would not die" and these are notes I took from them. The book didn't really give me a clear idea about what Price's argument was so I also read a Quartz article about that part of the story and, of course, Wikipedia came into it at some points.
A Brief Sketch of The Timelines to Bayes' Theorem
The Equations
Since it's hard to write out the equations in bullet points I'm going to write some simple versions here.
Bayes' Formulation
"The theory that would not die" notes that Bayes' didn't write out an equation, but it can be written out something like this. \[ P(\textit{cause}|\textit{effect}) = \frac{P(\textit{effect}|\textit{cause}) P(\textit{cause})}{P(\textit{effect})} \]
Laplace's First Version
Originally Laplace didn't have the prior's in his equation (I'll substitute C for cause, E for effect and C' for not our theorized cause). \[ P(C|E) = \frac{P(E|C)}{\sum P(E|C')} \]
Laplace's Final Version
\[ P(C|E) = \frac{P(E|C)P_{\textit{prior}}(C)}{\sum P(E|C') P_{\textit{prior}} (C')} \]