Published
Edited
Sep 5, 2020
1 star
Insert cell
Insert cell
FlockModel = (await import("https://agentscript.org/models/FlockModel.js")).default
Insert cell
md`
Next we'll initialize the model with a 32x16 (radial) rectangular world, call \`setup()\` to initalize the model, and return the model as the cell name.
`
Insert cell
model = {
const world = AS.World.defaultWorld(32, 16)
const model = new FlockModel(world)
model.setup()
return model
}
Insert cell
Insert cell
run = {
const width = model.world.width * patchSize
const height = model.world.height * patchSize
const svg = d3.select(DOM.svg(width, height))
.attr('style', 'border: 1px solid; padding: 10');

const g = svg.append('g')

g.call(transform)
.call(appendPatches)
.call(appendTurtles);

// the above called only once, the loop repeats
while (true) {
model.step()
draw(g)
yield svg.node()
}
}
Insert cell
Insert cell
transform = g => g.attr(
'transform',
`
scale(${patchSize}, ${-patchSize})
translate(${-model.world.minXcor}, ${-model.world.maxYcor})
`
)
Insert cell
appendPatches = g => g
.selectAll('rect')
.data(model.patches)
.enter()
.append('rect')
.attr('x', d => d.x - 0.5) // note the .5 outset, patch coords
.attr('y', d => d.y - 0.5) // are in the patch center! Cool.
.attr('width', 1)
.attr('height', 1)
.attr('vector-effect', 'non-scaling-stroke')
.attr(
'style',
d => `fill: ${randomLightGray()}; stroke: gray; stroke-width: 0.5;`
)
Insert cell
appendTurtles = g => {
g
.append('defs')
.append('g')
.attr('id', 'dart')
.append('polygon')
.attr('points', '0.5,0, -0.5,0.4, -0.25,0, -0.5,-0.4')
// .attr('transform', 'scale(2)')
.attr('transform', `scale(${turtleSize})`)
.attr('vector-effect', 'non-scaling-stroke')
.attr('style', 'stroke: black; stroke-width: 1px')

g
.selectAll('.dart')
.data(model.turtles)
.enter()
.append('use')
.attr('xlink:href', '#dart')
.attr('style', d => `fill: ${randomColor()}`)
}
Insert cell
Insert cell
draw = g => {
g
.selectAll('use')
// .data(model.turtles)
.attr(
'transform',
d => `translate(${d.x},${d.y}) rotate(${d.theta * 180 / Math.PI})`
)
}
Insert cell
Insert cell
function randomLightGray() {
const g = randomInt2(200, 255)
return `rgb(${g},${g},${g})`
}
Insert cell
function randomColor() {
const rgb = () => Math.round((randomInt2(0, 3) * 255) / 2)
return `rgb(${rgb()},${rgb()},${rgb()})`
}

Insert cell
randomInt2 = (min, max) => min + Math.floor(Math.random() * (max - min))

Insert cell
patchSize = 13
// patchSize = width / model.world.numX
Insert cell
turtleSize = 1.25
Insert cell
Insert cell
AS = import("https://agentscript.org/dist/agentscript.esm.js")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more