Releases: scottpdo/flocc
0.3.6
0.3.5
New Environment
helper: KDTree
A good overview of the k-d tree data structure here: https://en.wikipedia.org/wiki/K-d_tree
The flocc.KDTree
implementation, when used in Environment
s, can greatly accelerate models like Flocking, or any model where an Agent
needs to be have access to neighbors within a certain distance (and where looping over all Agent
s in the Environment
would be expensive).
API
Instantiating:
// first parameter = agents to include in the KDTree
// second parameter = # of dimensions (currently supports 2 or 3)
const tree = new KDTree(environment.getAgents(), 3);
environment.use(tree);
Getting all Agent
s within a certain distance of another Agent
, Vector
, or point:
const agentNeighbors = tree.agentsWithinDistance(agent, 20);
const vectorNeighbors = tree.agentsWithinDistance(new Vector(1, 2, 3), 20);
const pointNeighbors = tree.agentsWithinDistance({ x: 1, y: 2, z: 3 }, 20);
// all return an array of Agents (if an Agent is the first parameter, it is excluded from the result)
Getting the nearest neighbor of an Agent
, Vector
, or point:
const agentNearest = tree.nearestNeighbor(agent);
const vectorNearest = tree.nearestNeighbor(new Vector(1, 2, 3));
const pointNearest = tree.nearestNeighbor({ x: 1, y: 2, z: 3 });
// all return a single Agent that is the nearest neighbor
0.3.4
The utils.median
function was previously using Array.sort
without any compare function. Horribly, just really awfully, this native function sorts numbers by ascending place value of the highest place, like this:
1, 10, 100, 2, 20, 200, 3, 30, 300
instead of:
1, 2, 3, 10, 20, 30, 100, 200, 300
This bug has officially been SQUASHED. Yikes.
0.3.3
0.3.2
Add aboveMax
and belowMin
boolean options to the Histogram. If either are set to true, will add additional bucket(s) for, respectively, all values above the given maximum or below the given minimum.
Note that this changes the total number of buckets, so if you specify 5 buckets (for a range of 0-1, corresponding to 0-0.2, 0.2-0.4, etc.), setting both to true
will draw a total of 7 buckets, as in this screenshot:
Ex.
const histogram = new Histogram(environment, {
aboveMax: true,
belowMin: true,
buckets: 5
});
histogram.mount("#container");
histogram.metric("someValue");
0.3.1
Tick Options
Environment.tick
(and the subclass GridEnvironment.tick
) can now take either no parameters, a number, or a configuration object that will determine what happens when it ticks.
The options thus look like:
environment.tick(); // standard
environment.tick(10); // ticks 10 times
environment.tick({
randomizeOrder: true
}); // ticks once with the order randomized
environment.tick({
count: 5,
randomizeOrder: true
}); // ticks 5 times with the order randomized
Passing this object will randomize the order (using utils.shuffle
) in which agents get looped over and rules executed on each tick. Currently environments default to looping over agents in the order they were added to the environment, but with this configuration object you can override that default and randomize order.
0.3.0
Two big new introductions to the Flocc family are:
Lisp-like Rules
A new constructor, Rule
, can be used in place of a function in agent.addRule(rule)
. So far these Rule
s are less efficient than using functions directly, but have a lot of promise in giving the rules agents follow a tangible data structure, rather than interpreted from function syntax. Documentation to come.
Ex.
const steps = [
['local', 'x', 10],
['local', 'y', 20],
[
'set',
'pos',
['vector', ['local', 'x'], ['local', 'y']
]
];
const rule = new Rule(steps);
agent.addRule(rule);
Equivalent to:
function rule(agent) {
const x = 10;
const y = 20;
agent.set('pos', new Vector(x, y));
}
agent.addRule(rule);
Histogram Renderer
Like the LineChartRenderer
, a Histogram
visualizes aggregate data, by sorting agent data into 'buckets' and depicting the relative size (# of agents) in each bucket (say, 0-10 vs. 10-20 vs. 20-30).
Ex.
const histogram = new Histogram(environment, {
buckets: 6,
min: 0,
max: 90
});
histogram.mount('#histogram');
histogram.metric('age'); // key of agent data to bucket
0.2.7
CanvasRenderer
- New
shape
option for Agents being rendered by a CanvasRenderer:rect
const agent = new Agent();
agent.set('shape', 'rect');
agent.set({
x: 10,
y: 20,
width: 4,
height: 1
});
This agent will be drawn as a black (default color
value) rectangle 4 pixels wide by 1 pixel high at (10, 20)
.
- CanvasRenderer also now respects
window.devicePixelRatio
(should look crisper on retina screens).
0.2.6
Environment
Environments now extend the Agent class, so they inherit all Agent methods (.set
, .get
, .getData
, .increment
and .decrement
).
Agent
When passing a function as a value to the .set(key, value)
method, the function now takes the agent as its only parameter. Example:
const train1 = new Agent();
train1.set('destination', 'New York');
const train2 = new Agent();
train2.set('destination', 'Chicago');
// this function will be used as an alias to the agent's destination,
// returning it in lowercase format
function destinationLowercase(agent) {
return agent.get('destination').toLowerCase();
}
train1.set('destinationLowercase', destinationLowercase);
train2.set('destinationLowercase', destinationLowercase);
train1.get('destinationLowercase'); // returns 'new york'
train2.get('destinationLowercase'); // returns 'chicago'
0.2.5
Version 0.2.4 introduced the possibility of an agent's function value calling itself and entering an infinite loop.
This patches that by throwing an error if a reference to an agent's function value ends up calling itself and logging that info for the user.