Skip to content

Releases: scottpdo/flocc

0.3.6

03 Jan 21:29
3fed83e
Compare
Choose a tag to compare

Fix two Histogram bugs:

  • Bug where multiple Histograms on one page could only use one set of options (inheriting configuration option across instances)
  • Bug where right-most bucket wasn't displaying any values unless aboveMax was set to true

0.3.5

12 Dec 18:40
9094dcc
Compare
Choose a tag to compare

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 Environments, 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 Agents 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 Agents 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

06 Dec 21:21
34a64e4
Compare
Choose a tag to compare

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

02 Dec 00:37
Compare
Choose a tag to compare

Removed an extraneous console.log in Histogram.

0.3.2

01 Dec 11:47
901f506
Compare
Choose a tag to compare

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:

Screenshot from 2019-12-01 06-45-56

Ex.

const histogram = new Histogram(environment, {
  aboveMax: true,
  belowMin: true,
  buckets: 5
});
histogram.mount("#container");
histogram.metric("someValue");

0.3.1

18 Nov 11:06
dee9b3a
Compare
Choose a tag to compare

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

09 Nov 23:27
87af10c
Compare
Choose a tag to compare

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 Rules 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

23 Oct 20:52
d1e14f9
Compare
Choose a tag to compare

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

16 Oct 14:26
4c2edad
Compare
Choose a tag to compare

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

12 Oct 20:30
d6e913f
Compare
Choose a tag to compare

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.