xxxxxxxxxx
var segs = [];
var intersections = [];
var clicked = false;
var numSegs = 12;
var lineLength = 300;
var dotSize = 20;
function setup() {
angleMode(DEGREES);
createCanvas(400, 400);
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)]
}