Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@johnburnmurdoch
Last active February 26, 2018 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnburnmurdoch/912c1406945031bbb6816de82ecfb030 to your computer and use it in GitHub Desktop.
Save johnburnmurdoch/912c1406945031bbb6816de82ecfb030 to your computer and use it in GitHub Desktop.
Generative line intersections
license: mit
scrolling: no
border: no

Generates a random field of lines, each of which grows in a straight line until it encounters any other line, at which point it stops.

Phase one of a generative art project inspired by Jared Tarbell's Substrate project.

<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<title>Intersections</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/d3/build/d3.min.js"></script>
<style>
body{ background: #ffffff }
/*canvas{ background: #212121 }*/
canvas{ background: #ffffff }
</style>
</head>
<body>
<canvas></canvas>
<script type='text/javascript'>
let width = 500,
height = 300,
DPR = window.devicePixelRatio || 1,
scaledWidth = width * DPR,
scaledHeight = height * DPR,
canvas = d3.select("canvas")
.attr('width', scaledWidth)
.attr('height', scaledHeight)
.style('width', `${width}px`)
.style('height', `${height}px`),
ctx = canvas.node().getContext('2d'),
timesUp = 10000,
tickLength = 0.04,
lines = [],
intersects = [];
ctx.scale(DPR, DPR);
ctx.strokeStyle = '#000000';
ctx.lineWidth = 0.5;
const sameSign = (a, b) => (a * b) > 0;
function intersect(a,b,c,d,p,q,r,s) {
let det, gamma, lambda;
det = (c - a) * (s - q) - (r - p) * (d - b);
if (det === 0) {
return false;
} else {
lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1);
}
}
function addLine(id){
let line = {
id: id,
intersects: [],
start: [Math.random()*width, Math.random()*height],
end: [0, 0],
// slope: d3.format('.2f')(Math.random()) * Math.PI * 2
// slope: [0,Math.PI/2,Math.PI,Math.PI*3/2][Math.floor((Math.random()*4))]
slope: [0,Math.PI*0.333,Math.PI*0.666,Math.PI,Math.PI*1.333, Math.PI*1.666][Math.floor((Math.random()*6))]
};
lines.push(line);
}
d3.range(0,180).map((i) => addLine(i));
function draw(t){
let nLines = lines.length;
let linesLeft = lines.filter(f => f.intersects.length == 0);
linesLeft.forEach(l => {
let to = l.end = [l.start[0]+Math.cos(l.slope)*t*tickLength,
l.start[1]+Math.sin(l.slope)*t*tickLength];
for(let index=0; index < lines.length; index++){
let d = lines[index];
if(intersect(...d.start, ...d.end, ...l.start, ...l.end) == 1 && intersects.indexOf([l.id,d.id].sort((a,b) => a-b).join('_')) < 0){
l.intersects.push(1);
intersects.push([l.id,d.id].sort((a,b) => a-b).join('_'));
break;
}
}
if(to[0] >= 0 && to[0] <= width && to[1] >= 0 && to[1] <= height && l.intersects.length == 0){
/* ctx.fillRect(l.start[0]-2, l.start[1]-2, 4, 4) ;*/
ctx.moveTo(...l.start);
ctx.lineTo(...to);
ctx.stroke();
}else{
/* console.log(`Line ${l.id} hit edge, ${lines.length} left`); */
nLines -= 1;
}
})
if(nLines == 0){
console.log('CEASE')
timer.stop();
}
}
let timer = d3.interval(function(elapsed) {
draw(elapsed);
/* if (elapsed > timesUp) timer.stop(); */
}, 25);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment