var segs = []; var intersections = []; var clicked = false; var numSegs = 12; var lineLength = 300; var dotSize = 20; function setup() { angleMode(DEGREES); createCanvas(700, 700); resetLines(); findIntersections(); } function draw() { background(255); //creates a new set of segments if the mouse is clicked if(clicked){ resetLines(); findIntersections(); clicked = false; } drawSegs(); drawIntersections(); } function drawSegs(){ for(i = 0; i < numSegs; i++){ segs[i].drawSeg(); } } function drawIntersections(){ for(i = 0; i< intersections.length; i++){ intersections[i].drawIntersection(); } } function mousePressed() { clicked = true; } function Segment(x1, x2, y1, y2){ this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; this.drawSeg = function(){ stroke(0); strokeWeight(2); line(this.x1, this.y1, this.x2, this.y2); } } function Intersection(x, y){ this.xPos = x; this.yPos = y; this.drawIntersection = function(){ strokeWeight(0); fill(0, 100); ellipse(this.xPos, this.yPos, dotSize, dotSize); } } function resetLines(){ segs = []; for(i = 0; i < numSegs; i++){ var x1 = random(0, width); var y1 = random(0, height); var secondPoint = setSecondPoint(x1, y1); var x2 = secondPoint[0]; var y2 = secondPoint[1]; newSeg = new Segment(x1, x2, y1, y2); segs.push(newSeg); } } //Calculates the second point by selecting a point at the edge of a circle //where the radius is the desired length of the lines and the center //is the first point function setSecondPoint(x1, y1){ var angle = random(0, 360); var y2 = sin(angle) * lineLength + y1; var x2 = cos(angle) * lineLength + x1; //If the second point is outside the canvas, another one is calculated while(x2 < 0 || x2 >= width || y2 < 0 || y2 >= height){ angle = random(0, 360); y2 = sin(angle) * lineLength + y1; x2 = cos(angle) * lineLength + x1; } return [x2, y2]; } //iterates through all of the segments to find the intersections function findIntersections(){ intersections = []; for(firstInd = 0; firstInd < numSegs; firstInd++){ firstSeg = segs[firstInd]; for(secInd = 0; secInd < numSegs; secInd++){ secondSeg = segs[secInd]; intersection = findIntersection(firstSeg.x1, firstSeg.y1, firstSeg.x2, firstSeg.y2, secondSeg.x1, secondSeg.y1, secondSeg.x2, secondSeg.y2); if(intersectionIsValid(intersection)){ intersections.push(new Intersection(intersection[0], intersection[1])); } } } } //check that the intersection exists and hasn't already been discovered function intersectionIsValid(intersection){ if(intersection == false){ return false; } for(i = 0; i < intersections.length; i++){ if(intersections[i].xPos == intersection[0] && intersections[i].yPos == intersection[1]){ return false; } } return true; } //Paul Bourke's equation for finding the intersection of two lines //Code courtesy of Leo Bottaro function findIntersection(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 [floor(x), floor(y)] } |