Skip to content

Instantly share code, notes, and snippets.

@sifbuilder
Created July 17, 2016 19:55
Show Gist options
  • Save sifbuilder/c5e629b377ad6b8ff055d75fb9c17359 to your computer and use it in GitHub Desktop.
Save sifbuilder/c5e629b377ad6b8ff055d75fb9c17359 to your computer and use it in GitHub Desktop.
ringforce i, circumscribing rings in a voronoi triangles diagram of heavy seeds moving in a contained field area
ringforce, circumscribing rings in a voronoi triangles diagram of heavy seeds moving in a contained field area
/* ------------------ */
/* index-controls.js */
/* ------------------ */
// ---------------- // drag listeners
var dragstarted = function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
}
function dragged(d) {
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
}
// ---------------- // mouse listeners
function pauseEvent(e){
if(e.stopPropagation) e.stopPropagation();
if(e.preventDefault) e.preventDefault();
e.cancelBubble=true;
e.returnValue=false;
return false;
}
function mousemove(svgElement) {
moving = 1
mousePosition = d3.mouse(svgElement) // updateMousePos
var e = d3.event
pauseEvent(e)
}
function mouseleave() {
moving = 0
// stopParticles();
}
function mousedown() {
// mousedown = 1
// updateMousePos();
// startParticles();
}
function mousedown() {
// touchstart = 1
// updateMousePos();
// startParticles();
}
function touchmove(svgElement) {
moving = 1
mousePosition = d3.mouse(svgElement) // updateMousePos
var e = d3.event
pauseEvent(e)
}
function mouseup() {
// mouseup = 1
// stopParticles();
}
function touchend() {
// touchend = 1
// stopParticles();
}
/* ------------------ */
/* index-data.js */
/* ------------------ */
// =================================== nodes
var nodes = [];
var links = [];
var nodesCollection = [{
id: 0,
group: 1,
rotr: 100,
rtype: "circle",
color: "red",
offset: 20,
timelimit: 2000,
starttime: undefined,
elapsed: 0,
scale: 1,
move: false,
links: [{
source: 0, // red
target: 1, // blue
index: 1,
},
// {
// source: 0, // red
// target: 3, // black
// index: 2,
// },
{
source: 0, // red
target: 4, // grey
index: 2,
}],
charge: -2,
t: 1,
r: 2,
x: 15,
y: 50,
vx: 0,
vy: 0,
}
, {
id: 1,
group: 1,
rotr: 100,
rtype: "circle",
color: "blue",
offset: 20,
timelimit: 2000,
starttime: undefined,
elapsed: 0,
links: [
{
source: 1, // blue
target: 2, // green
index: 3,
},
{
source: 1, // blue
target: 3, // green
index: 4,
},
],
charge: -1,
mass: 0,
r: 2,
t: 1,
x: 80,
y: 50,
vx: 0,
vy: 0,
scale: 1,
move: false,
}
, {
id: 2, // green
group: 1,
rotr: 100,
rtype: "circle",
color: "green",
offset: 20,
timelimit: 2000,
starttime: undefined,
elapsed: 0,
x: 80,
fy: 50,
vx: 0,
vy: 0,
links: [],
charge: 1,
mass: 0,
r: 2,
t: 1,
x: 60,
y: 50,
vx: 0,
vy: 0,
scale: 1,
move: false,
}
, {
id: 3,
group: 1,
rotr: 100,
rtype: "circle",
color: "black",
offset: 20,
timelimit: 2000,
starttime: undefined,
elapsed: 0,
links: [],
charge: -3,
mass: 0,
r: 2,
t: 1,
x: 90,
y: 50,
vx: 0,
vy: 0,
scale: 1,
move: false,
}
, {
id: 4,
group: 1,
rotr: 100,
rtype: "circle",
color: "grey",
offset: 20,
timelimit: 2000,
starttime: undefined,
elapsed: 0,
scale: 1,
move: false,
links: [],
charge: -2,
mass: 0,
r: 2,
t: 1,
x: 10,
y: 50,
vx: 0,
vy: 0,
}
]
var nodes = []
nodes = [nodesCollection[0],
nodesCollection[1],
nodesCollection[2],
nodesCollection[3],
nodesCollection[4],
]
var links = nodes
.reduce(function(a, b, i, v) {
var ls = b.links
.filter(function(obj) {
return (nodes[obj.target] !== undefined)
})
var ln = ls.map(function(d) {
return {
source: nodes[d.source],
target: nodes[d.target],
}
})
return a.concat(ln)
}, [])
// =================================== voronoi
// create the Voronoi diagram: partitioning of a plane into regions based on distance to points in a specific subset of the plane
var getSeeds = function getSeeds(x0, y0, x1, y1, vx, vy) {
for (var i = 0, r = []; i < n; ++i)
r[i] = {
x: x0 + Math.random() * (x1 - x0),
y: y0 + Math.random() * (y1 - y0),
vx: vx || 0,
vy: vy || 0,
r: 0.5,
}
return r
}
/* ------------------ */
/* index-elems.js */
/* ------------------ */
// ==================== lanes
var drawLanesSimulation = function drawLanesSimulation() { // drawLanesSimulation
simulationRolls
.on("tick", function() {
tickRollsForce(this.alpha())
redrawLanesDiagram()
})
.on("end", function() {
})
}
var drawLanesDiagram = function drawLanesDiagram() { // drawLanesDiagram
var linkGroup = d3.select('svg').selectAll('g.links').data(['links']).enter().append("g").attr("class", "links")
var linkElements = d3.select('svg').select("g.links").selectAll("line").data(links)
linkElements.enter().append("line").call(drawLink)
linkElements.call(drawLink)
linkElements.exit().remove()
var nodeGroup = d3.select('svg').selectAll('g.nodes').data(['nodes']).enter().append("g").attr("class", "nodes")
var rectElements = d3.select('svg').select("g.nodes").selectAll("rect").data(nodes, function(d) { return d.id })
rectElements.enter().append("rect").call(drawNodeRect)
rectElements.call(drawNodeRect)
rectElements.exit().remove()
var nodeElements = d3.select('svg').select("g.nodes").selectAll("circle").data(nodes, function(d) { return d.id })
nodeElements.enter().append("circle").call(drawNodeCircle)
nodeElements.call(drawNodeCircle)
nodeElements.exit().remove()
var textElements = d3.select('svg').select("g.nodes").selectAll("text").data(nodes, function(d) { return d.id })
textElements.enter().append("text").call(drawNodeText)
textElements.call(drawNodeText)
textElements.exit().remove()
}
var redrawLanesDiagram = function redrawLanesDiagram() { // redrawLanesDiagram
// nodes have been redefined in the simulation
var linkGroup = d3.select('svg').selectAll('g.links').data(['links']).enter().append("g").attr("class", "links")
var linkElements = d3.select('svg').select("g.links").selectAll("line").data(links)
linkElements.enter().append("line").call(redrawLink)
linkElements.call(redrawLink)
linkElements.exit().remove()
var nodeGroup = d3.select('svg').selectAll('g.nodes').data(['nodes']).enter().append("g").attr("class", "nodes")
var rectElements = d3.select('svg').select("g.nodes").selectAll("rect").data(nodes, function(d) { return d.id })
rectElements.enter().append("rect").call(redrawNodeRect)
rectElements.call(redrawNodeRect)
rectElements.exit().remove()
var nodeElements = d3.select('svg').select("g.nodes").selectAll("circle").data(nodes, function(d) { return d.id })
nodeElements.enter().append("circle").call(redrawNodeCircle)
nodeElements.call(redrawNodeCircle)
nodeElements.exit().remove()
var textElements = d3.select('svg').select("g.nodes").selectAll("text").data(nodes, function(d) { return d.id })
textElements.enter().append("text").call(redrawNodeText)
textElements.call(redrawNodeText)
textElements.exit().remove()
}
function drawNodeRect(nodeRect) { // drawNodeRect
nodeRect
.attr("x", function(d) { return xa(d.x - d.r / 8) })
.attr("y", function(d) { return ya(d.y) - (height / 2) }) // ya(d.y - d.r) })
.attr("height", function (d) { return height }) // xa(2 * d.r) })
.attr("width", function (d) { return ya(d.r / 4) })
.attr("stroke-width", 1)
.style("stroke", "grey")
.style("fill", function(d) { return d.color })
}
function redrawNodeRect(nodeRect) { // redrawNodeRect
nodeRect
.attr("x", function(d) { return xa(d.x - d.r / 8) })
.attr("y", function(d) { return ya(d.y) - (height / 2) }) // ya(d.y - d.r) })
.attr("height", function (d) { return height }) // xa(2 * d.r) })
.attr("width", function (d) { return ya(d.r / 4) })
.style("fill", function(d) { return "transparent" }) // d.color
.style("stroke", "transparent") // grey
}
function drawNodeText(nodeText) { // drawNodeText
nodeText
.attr("x", function(d) { return xa(d.x) })
.attr("y", function(d) { return ya(d.y) })
.text(function(d) { return "" + Math.round(xa(d.x)) + ":" + Math.round(ya(d.y))})
.style("font-size", function(d) { return ma(d.t) })
.style("font-family", "sans-serif")
.style("fill", "white")
.style("text-anchor", "middle")
}
function redrawNodeText(nodeText) { // redrawNodeText
nodeText
.attr("x", function(d) { return xa(d.x) })
.attr("y", function(d) { return ya(d.y) })
.text(function(d) { return "" + Math.round(xa(d.x)) + ":" + Math.round(ya(d.y))})
.style("font-size", function(d) { return ma(d.t) })
.style("fill", "transparent") // white
}
function drawLink(link) { // drawLink
link
.attr("x1", function(d) { return xa(d.source.x) })
.attr("y1", function(d) { return ya(d.source.y) })
.attr("x2", function(d) { return xa(d.target.x) })
.attr("y2", function(d) { return ya(d.target.y) })
.attr("stroke-width", 1)
.style("stroke", "red")
}
function redrawLink(link) { // redrawLink
link
.attr("x1", function(d) { return xa(d.source.x) })
.attr("y1", function(d) { return ya(d.source.y) })
.attr("x2", function(d) { return xa(d.target.x) })
.attr("y2", function(d) { return ya(d.target.y) })
.style("stroke", "transparent") // grey
.style("fill", function(d) { return "transparent" })
}
function drawNodeCircle(nodeCircle) { // drawNodeCircle
nodeCircle
.attr("cx", function(d) { return xa(d.x) })
.attr("cy", function(d) { return ya(d.y) })
.attr("r", function(d) { return ma(d.r) })
.style("fill", function(d) { return d.color })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
}
function redrawNodeCircle(nodeCircle) { // redrawNodeCircle
nodeCircle
.attr("cx", function(d) { return xa(d.x) })
.attr("cy", function(d) { return ya(d.y) })
.attr("r", function(d) { return ma(d.r) })
.style("fill", function(d) { return "transparent" }) // d.color
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
}
// ==================== rings - voro
var drawVoroSimulation = function drawVoroSimulation() { // drawVoroSimulation
simulationVoro
.on("tick", function() {
contentionForce(this.alpha(), seeds, seedsArea)
tickVoroForce(this.alpha())
redrawVoroDiagam()
})
.on("end", function() {
})
}
var drawVoroDiagam = function drawVoroDiagam() { // drawVoroDiagam
var rings = polygons.map(function(d) {return inscribeTriangle(xa(d[0][0]), ya(d[0][1]), xa(d[1][0]), ya(d[1][1]), xa(d[2][0]), ya(d[2][1]))})
var rs = rings.map(function(d) { return d.radius })
stateRing.radiusMin = Math.min(...rs)
stateRing.radiusMax = Math.max(...rs)
var seedsGroup = d3.select('svg').selectAll('g.seeds').data(['g_seeds']).enter().append("g").attr("class", "seeds")
var seedElements = d3.select('svg').select("g.seeds").selectAll("circle").data(seeds)
seedElements.enter().append("circle").call(drawSeed)
seedElements.call(drawSeed)
seedElements.exit().remove()
var polygonsGroup = d3.select('svg').selectAll('g.polygons').data(['g_polygons']).enter().append("g").attr("class", "polygons")
var polygonElements = d3.select('svg').select("g.polygons").selectAll("path").data(polygons)
polygonElements.enter().append("path").call(drawPolygon);
polygonElements.call(drawPolygon)
polygonElements.exit().remove()
var ringsGroup = d3.select('svg').selectAll('g.rings').data(['g_rings']).enter().append("g").attr("class", "rings")
var ringElements = d3.select('svg').select("g.rings").selectAll("circle").data(rings)
ringElements.enter().append("circle").call(drawRing)
ringElements.call(drawRing)
ringElements.exit().remove()
}
var redrawVoroDiagam = function redrawVoroDiagam() { // redrawVoroDiagam
var rings = polygons.map(function(d) {return inscribeTriangle(xa(d[0][0]), ya(d[0][1]), xa(d[1][0]), ya(d[1][1]), xa(d[2][0]), ya(d[2][1]))})
var rs = rings.map(function(d) { return d.radius })
stateRing.radiusMin = Math.min(...rs)
stateRing.radiusMax = Math.max(...rs)
var seedsGroup = d3.select('svg').selectAll('g.seeds').data(['g_seeds']).enter().append("g").attr("class", "seeds")
var seedElements = d3.select('svg').select("g.seeds").selectAll("circle").data(seeds)
seedElements = d3.select('svg').select("g.seeds").selectAll("circle").data(seeds)
seedElements.enter().append("circle").call(redrawSeed)
seedElements.call(redrawSeed);
seedElements.exit().remove()
var polygonsGroup = d3.select('svg').selectAll('g.polygons').data(['g_polygons']).enter().append("g").attr("class", "polygons")
var polygonElements = d3.select('svg').select("g.polygons").selectAll("path").data(polygons)
polygonElements.enter().append("path").call(redrawPolygon);
polygonElements.call(redrawPolygon)
polygonElements.exit().remove()
// projection
var ringsGroup = d3.select('svg').selectAll('g.rings').data(['g_rings']).enter().append("g").attr("class", "rings")
var ringElements = d3.select('svg').select("g.rings").selectAll("circle").data(rings)
ringElements.enter().append("circle").call(redrawRing)
ringElements.call(redrawRing)
ringElements.exit().remove()
}
function drawSeed(seed) { // drawSeed
seed
.attr("cx", function(d, i) { return d.x} )
.attr("cy", function(d, i) { return d.y} )
.attr("r", function(d, i) { return d.r })
.style("fill", function(d, i) { return 'transparent' })
.attr("stroke", "red")
}
function redrawSeed(seed) { // redrawSeed
seed
.attr("cx", function(d, i) { return xa(d.x)} )
.attr("cy", function(d, i) { return ya(d.y)} )
.attr("r", function(d, i) { return ma(d.r) })
.style("fill", function(d, i) { return 'transparent' }) // gold
.attr("stroke", "transparent ") // "transparent"
}
function drawPolygon(polygon) { // drawPolygon
polygon
.attr("d", function(d) { return d ? "M" + d.join("L") + "Z" : null; })
.attr("stroke", "#000")
.style("fill", function(d, i) { return 'transparent' })
}
function redrawPolygon(polygon) { // redrawPolygon
polygon
.attr("d", function(d) {
// return d ? "M" + d.join("L") + "Z" : null; })
return d ? "M" + d.map(function(p) {return [xa(p[0]), ya(p[1])]}).join("L") + "Z" : null; })
.attr("stroke", "transparent") // transparent brown
.style("fill", function(d, i) { return 'transparent' }) // transparent
}
function drawRing(ring) { // drawRing
ring
.attr('cx', function(d) {return d[0] })
.attr('cy', function(d) {return d[1] })
.attr('r', function(d) {return d.radius })
.style("fill", function(d, i) { return 'transparent' })
.attr("stroke", "grey")
}
function redrawRing(ring) { // redrawRing - no projection
ring
.attr('cx', function(d) {return d[0] })
.attr('cy', function(d) {return d[1] })
.attr('r', function(d) {return d.radius })
.style("fill", function(d, i) { return 'transparent' }) // transparent // gold
.attr("stroke", function(d) {
var d = Math.floor(((d.radius - stateRing.radiusMin) / (stateRing.radiusMax - stateRing.radiusMin)) * 256)
var c = d3.interpolatePlasma(d / 256)
return c })
}
function inscribeTriangle(x0, y0, x1, y1, x2, y2) {
var x01 = x0 - x1, y01 = y0 - y1,
x02 = x0 - x2, y02 = y0 - y2,
x12 = x1 - x2, y12 = y1 - y2,
l01 = Math.sqrt(x01 * x01 + y01 * y01),
l02 = Math.sqrt(x02 * x02 + y02 * y02),
l12 = Math.sqrt(x12 * x12 + y12 * y12),
k0 = l01 / (l01 + l02),
k1 = l12 / (l12 + l01),
center = segmentIntersection(x0, y0, x1 - k0 * x12, y1 - k0 * y12, x1, y1, x2 + k1 * x02, y2 + k1 * y02);
center.radius = Math.sqrt((l02 + l12 - l01) * (l12 + l01 - l02) * (l01 + l02 - l12) / (l01 + l02 + l12)) / 2;
return center;
}
function segmentIntersection(x0, y0, x1, y1, x2, y2, x3, y3) {
var x02 = x0 - x2, y02 = y0 - y2,
x10 = x1 - x0, y10 = y1 - y0,
x32 = x3 - x2, y32 = y3 - y2,
t = (x32 * y02 - y32 * x02) / (y32 * x10 - x32 * y10);
return [x0 + t * x10, y0 + t * y10];
}
// ==================== common
function drawSvg(svgElement) { // drawNodeRect
svgElement
.attr("width", widthPct)
.attr("height", heightPct)
.style('border', '1px solid lightgrey')
.on("touchmove mousemove", function() {mousemove(this)})
.on("mouseleave", function() {mouseleave(this)})
.on("mousedown", function() {mousedown(this)})
.on("touchstart", function() {touchstart(this)})
.on("touchmove", function() {touchmove(this)})
.on("mouseup", function() {mouseup(this)})
.on("touchend", function() {touchend(this)})
}
/* ------------------ */
/* index-lanes-tick.js */
/* ------------------ */
// ---------------- force field
function tickRollsForce(alpha) {
hpct = parseInt(svgElement.style("width"), 10) / 100
vpct = parseInt(svgElement.style("height"), 10) / 100
mpct = hpct + vpct / 2
var dir = 0
var k = 1
var p = 0.01
var c = 50
var q = 1
if (moving == 0) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].fx === undefined) nodes[i].vxTmp = nodes[i].vx, nodes[i].fx = nodes[i].x, nodes[i].fxTmp = 'set'
if (nodes[i].fy === undefined) nodes[i].vyTmp = nodes[i].vy, nodes[i].fy = nodes[i].y, nodes[i].fyTmp = 'set'
}
}
if (moving == 1) {
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].fxTmp === 'set') nodes[i].vx = nodes[i].vxTmp, nodes[i].fx = undefined, nodes[i].fxTmp = undefined
if (nodes[i].fyTmp === 'set') nodes[i].vy = nodes[i].vyTmp, nodes[i].fy = undefined, nodes[i].fyTmp = undefined
}
tickingNodes(alpha)
}
function tickingNodes(alpha) { // do when force is active
for (var i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i];
if (node.color == 'red') { // red
q = (node.x - c ) / c // -1 | 0 | +1
node.vx = node.vx - q * p
node.x = node.x + node.vx
node.fy = node.y
}
if (node.color == 'blue') { // blue
q = (node.x - c ) / c // -1 | 0 | +1
node.vx = node.vx - q * p
node.x = node.x + node.vx
node.fy = node.y
}
if (node.color == 'green') { // green
q = (node.x - c ) / c // -1 | 0 | +1
node.vx = node.vx - q * p
node.x = node.x + node.vx
node.fy = node.y
}
if (node.color == 'black') { // black
node.fx = node.x
node.fy = node.y
}
if (node.color == 'grey') { // grey
node.fx = node.x
node.fy = node.y
}
}
}
}
function force3(alpha) {
node = nodes[2];
if (node.vx > 0 && node.x >= 500) node.vx = -node.vx
if (node.vx < 0 && node.x <= 100) node.vx = -node.vx
}
/* ------------------ */
/* index-rings-tick.js */
/* ------------------ */
function tickVoroForce(alpha) { // ticking force
hpct = parseInt(svgElement.style("width"), 10) / 100
vpct = parseInt(svgElement.style("height"), 10) / 100
mpct = hpct + vpct / 2
var dir = 0
var k = 1
var p = 0.01
var c = 50
var q = 1
if (moving == 0) {
for (var i = 0; i < seeds.length; i++) {
if (seeds[i].fx === undefined) seeds[i].vxTmp = seeds[i].vx, seeds[i].fx = seeds[i].x, seeds[i].fxTmp = 'set'
if (seeds[i].fy === undefined) seeds[i].vyTmp = seeds[i].vy, seeds[i].fy = seeds[i].y, seeds[i].fyTmp = 'set'
}
}
if (moving == 1) {
for (var i = 0; i < seeds.length; i++) {
if (seeds[i].fxTmp === 'set') seeds[i].vx = seeds[i].vxTmp, seeds[i].fx = undefined, seeds[i].fxTmp = undefined
if (seeds[i].fyTmp === 'set') seeds[i].vy = seeds[i].vyTmp, seeds[i].fy = undefined, seeds[i].fyTmp = undefined
}
tickingSeeds(alpha)
}
}
function tickingSeeds(alpha) { // tick when force is active
for (i = 0; i < seeds.length; i++) {
var randNormal = d3.randomNormal(1.3, 2)
var randNormal2 = d3.randomNormal(0.5, 1.8)
seeds[i].vx = randNormal() * (Math.random() - 0.5)
seeds[i].vy += randNormal2()
}
seedsArea = {x0: nodes[0].x, y0: 0, x1:nodes[1].x, y1: 100}
extent = [[seedsArea.x0 + 1, seedsArea.y0 + 1], [seedsArea.x1 + 1 , seedsArea.y1 - 1]] // abs
voro = d3.voronoi().extent(extent)
dia = voro(seeds.map(function(d) {return [d.x, d.y]})) // pass an array of coordinates [[,], [,]]
polygons = dia.triangles()
redrawVoroDiagam() // REDRAW DIAGRAM
}
function contentionForce(alpha, items, area) { // contentionForce
for (var i = 0, n = items.length, node, k = alpha * 0.1; i < n; ++i) {
var item = items[i]
if (item.vx > 0 && item.x >= area.x1) item.vx = -item.vx
if (item.vx< 0 && item.x <= area.x0) item.vx = -item.vx
if (item.vy > 0 && item.y >= area.y1) item.vy = -item.vy
if (item.vy < 0 && item.y <= area.y0) item.vy = -item.vy
if (Math.abs(item.vx) < 0.05) item.vx *= 2
if (Math.abs(item.vy) < 0.05) item.vy *= 2
if (Math.abs(item.vx) > 0.5) item.vx /= 2
if (Math.abs(item.vy) > 0.5) item.vy /= 2
}
}
<html>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<body>
<script src="https://d3js.org/d3.v4.js"></script>
<!--
<script src="d3.v4.js"></script>
-->
<script src="index-data.js" charset="utf-8"></script>
<script src="index-elems.js" charset="utf-8"></script>
<script src="index-controls.js" charset="utf-8"></script>
<script src="index-lanes-tick.js" charset="utf-8"></script>
<script src="index-rings-tick.js" charset="utf-8"></script>
<script src="index.js" charset="utf-8"></script>
</body>
</html>
/* ------------------ */
/* index.js */
/* ------------------ */
// STATE
var stateRing = {}
var widthPct = '80%' //'100%' // 640 //
var heightPct = '80%' // '100%' // 480 //
var animationStep = 500;
var centerx = widthPct / 2
var centery = heightPct / 2
var moving = 1
var mousePosition = []
// RENDER
var svgContainer = d3.select("body").selectAll('svg').data(['svg'])
var svgElement = svgContainer.enter().append("svg").attr("id", "svg").attr("class", "svg").call(drawSvg)
// relative per one factors
var hpct = parseInt(svgElement.style("width"), 10) / 100
var vpct = parseInt(svgElement.style("height"), 10) / 100
var mpct = hpct + vpct / 2
// rel to abs coordinantes
var xa = function xa (d) { return d * hpct }
var ya = function ya (d) { return d * vpct }
var ma = function ma (d) { return d * mpct }
// abs coordinantes
var width = parseInt(svgElement.style("width"), 10)
var height = parseInt(svgElement.style("height"), 10)
stateRing.radiusMax = 0
stateRing.radiusMin = 0
stateRing.color = d3.interpolatePlasma
// console.log(color(3)) // 256
// color( ((3*r)%10 / 10) + (Math.random()* 3 /10))
// ==================================================================== simulationRolls
drawLanesDiagram()
var simulationRolls = d3.forceSimulation()
.alpha(1) // tick increments the current alpha by (alphaTarget - alpha) � alphaDecay
// tick then invokes each registered force, passing the new alpha
// tick decrements each node�s velocity by velocity � velocityDecay
// tick increments each node�s position by velocity
.alphaMin(0.001) // (0.001)
.alphaDecay(0.000228) // (0.0228)
.alphaTarget(0)
.velocityDecay(0.000) // (0.4) // each node�s velocity is multiplied by 1 - decay
simulationRolls
.nodes(nodes)
// .force("link", d3.forceLink().id(function(d) { return d.index; }))
// .force("charge", d3.forceManyBody().strength(-20)) // positive: attraction
.force("charge", d3.forceManyBody().strength(function(d) { return d.charge })) // positive: attraction
.force("collide", d3.forceCollide(function(d) {return 2 * d.r}).iterations(4)) //
// .force("center", d3.forceCenter(50, 50)) //
simulationRolls
.force("link")
// .links(links).strength(0) // .iterations(1).distance(5)
drawLanesSimulation()
// ==================================================================== voro sites
// ==================================================================== voro sites
// var voro = d3.voronoi().extent([[nodes[0].x, 1], [nodes[0].y, height - 1]])
var voro // voronoi
var dia // voronoi diagram
var polygons // polygons on dia sites
var rings // circumscribed circles in polygons
var extent = [] // extend of diagram
var seedsArea = {} // {x0, y0, x1, y1} area where the seeds are located
var n = 100, // number of sites
seeds = new Array(n), // also seeds or generators)
color = "blue", // color of the ...
radius = 10 // radius of the ...
seedsArea = {x0: nodes[0].x, y0: 0, x1:nodes[1].x, y1: 100}
extent = [[seedsArea.x0 + 1, seedsArea.y0 + 1], [seedsArea.x1 + 1 , seedsArea.y1 - 1]]
voro = d3.voronoi().extent(extent)
seeds = getSeeds(seedsArea.x0, seedsArea.y0, seedsArea.x1, seedsArea.y1, 0, 0) // get seeds {x, y, vx, vy} // in data for simulation
dia = voro(seeds.map(function(d) {return [d.x, d.y]})) // pass an array of coordinates [[,], [,]]
polygons = dia.triangles()
rings = polygons.map(function(d) {return inscribeTriangle(d[0][0], d[0][1],d[1][0], d[1][1],d[2][0], d[2][1])})
drawVoroDiagam()
var simulationVoro = d3.forceSimulation()
.alpha(1) // tick increments the current alpha by (alphaTarget - alpha) � alphaDecay
// tick then invokes each registered force, passing the new alpha
// tick decrements each node�s velocity by velocity � velocityDecay
// tick increments each node�s position by velocity
.alphaMin(0.001) // (0.001)
.alphaDecay(0.000228) // (0.0228)
.alphaTarget(0)
.velocityDecay(0.000) // (0.4) // each node�s velocity is multiplied by 1 - decay
// .initialize()
simulationVoro
.nodes(seeds)
.force("link", d3.forceLink().id(function(d) { return d.index; }))
// .force("charge", d3.forceManyBody().strength(-5)) // positive: attraction
// .force("charge", d3.forceManyBody().strength(function(d) { return d.charge })) // positive: attraction
.force("collide", d3.forceCollide(function(d) {return 2 * d.r}).iterations(4)) //
// .force("center", d3.forceCenter(50, 50)) //
simulationVoro
.force("link")
// .links(links).strength(0.5).iterations(1).distance(15)
drawVoroSimulation()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment