sapeck-Intersections

/* Sapeck    9/6/2017
"sapeck-Intersections"
60-212                        Carnegie Mellon University
Copyright (C) 2018-present  Sapeck
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
 
var NUM_LINES = 12
 
function setup() {
  createCanvas(720, 480)
  boolDoRefresh = true
}
 
function draw() {
  if (boolDoRefresh) {
    background(255);
 
		let lines = []
		let intersects = []
		for (let i=0;i<NUM_LINES;i++) {
			let thisLine = {
				x1: floor(random(0, width)),
				y1: floor(random(0, height)),
				y2: floor(random(0, height))
			}
			thisLine.x2 = floor(random(thisLine.x1+1, width))
			thisLine.m = (thisLine.y2 - thisLine.y1) / (thisLine.x2 - thisLine.x1)
			lines.push(thisLine)
		}
		for (let i=0;i<lines.length;i++) {
			for (let j=i+1;j<lines.length;j++) {
				if (i !== j) {
					let thisLine = lines[i]
					let testLine = lines[j]
 
					// My brute-force-test-x method that didn't entirely work
					// for (let thisX=thisLine.x1;thisX<=thisLine.x2;thisX+=0.1) {
					// 	let thisY = floor((thisLine.m * (thisX-thisLine.x1)) + thisLine.y1)
					// 	let testY = floor((testLine.m * (thisX-testLine.x1)) + testLine.y1)
					// 	if (thisY==testY) intersects.push({x: thisX, y: thisY})
					// }
 
					// Paul Bourke's method (see function defintion below for full citation)
					let x1 = thisLine.x1, x2 = thisLine.x2, x3 = testLine.x1, x4 = testLine.x2
					let y1 = thisLine.y1, y2 = thisLine.y2, y3 = testLine.y1, y4 = testLine.y2
					let intersection = intersect(x1, y1, x2, y2, x3, y3, x4, y4)
					if (intersection !== false) intersects.push({x: intersection.x, y: intersection.y})
				}
			}
		}
		for (let i=0;i<lines.length;i++) {
			let thisLine = lines[i]
			stroke(color(0,0,255))
			line(thisLine.x1, thisLine.y1, thisLine.x2, thisLine.y2)
		}
		for (let i=0;i<intersects.length;i++) {
			let intersection = intersects[i]
			noStroke();
			fill(color(255,0,0,50))
			ellipse(intersection.x,intersection.y,20,20)
		}
 
    boolDoRefresh = false
  }
}
 
function mousePressed() {
  boolDoRefresh = true
}
 
// line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/
// Determine the intersection point of two line segments
// Return FALSE if the lines don't intersect
function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
 
  // Check if none of the lines are of length 0
	if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) {
		return false
	}
 
	denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
 
  // Lines are parallel
	if (denominator === 0) {
		return false
	}
 
	let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator
	let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator
 
  // is the intersection along the segments
	if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
		return false
	}
 
  // Return a object with the x and y coordinates of the intersection
	let x = x1 + ua * (x2 - x1)
	let y = y1 + ua * (y2 - y1)
 
	return {x, y}
}