conye – Intersections

Hello world :-)! Here is the gif of my program in action:

gif of conye-intersections project

You can try it below! 

This is the code for it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var col, sliderback, r, g, b;
var lines = [];
var globalMag = 400; //control length of lines
var slider;
var sliderval;
 
function setup() {
    //basic setup
    frameRate(30);
    //these values will shift slightly each time a new line is made so we get a variety of similar colors!
    r = 110;
    g = 94;
    b = 120;
    createCanvas(720, 480);
    background("#F6EAFE");
 
    //making the slider to change the amount of lines
    sliderback = color(255, 255, 255, 150);
    slider = createSlider(12, 100, 12);
    sliderval = 12;
    noStroke();
    slider.position(15, 15);
    fill(sliderback);
    rect(5, 5, slider.width + 55, slider.height + 12);
 
    //run the program!!!
    iterate();
}
 
function mouseClicked() {
    sliderval = slider.value();
    iterate();
}
 
function draw() {
    //continuously check if slider value has changed and iterate if it has
    //this makes it so the image will change as the slider is dragged
    //sometimes mouseClicked() does the job but if you drag in a certain way it won't regiester as a click event
    if (sliderval != slider.value()) iterate();
    sliderval = slider.value();
}
 
//main part of the function that calls every time the slider is changed or the mouse is clicked
function iterate() {
    //reset canvas and lines array
    background("#F6EAFE");
    lines = [];
    createLines(lines, slider.value());
    //intersections are drawn before the lines because it looks prettier to have the circles behind the lines
    drawIntersections(lines);
    drawLines(lines);
    //the rest is just for the slider
    fill(sliderback);
    noStroke();
    rect(5, 5, slider.width + 55, slider.height + 10);
    fill(0);
    text(slider.value() + " lines", slider.width + 11, 20);
}
 
//generates lines and puts them in the array
function createLines(arr, num){
    for (var i = 0; i < num; i++) {
        var tempLine = new Line(Math.floor(random(0, 720)), Math.floor(random(0, 480)));
        arr.push(tempLine)
    }
}
 
//actually draws the lines on the canvas
function drawLines(arr) {
    //colors vary slightly to make it prettier
    col = color(r, g, b, 255);
    stroke(col);
    strokeWeight(3);
    for (var i = 0; i < arr.length; i++) {
        col = color(shiftColor(r), shiftColor(g), shiftColor(b), 255);
        stroke(col);
        line(arr[i].x, arr[i].y, arr[i].x + globalMag * arr[i].vec.x, arr[i].y + globalMag * arr[i].vec.y);
    }
}
 
//finds and then draws the intersections
function drawIntersections(arr) {
    noStroke();
    fill(255, 204, 255);
    for (var i = 0; i < lines.length; i++) {
        for (var j = i + 1; j < lines.length; j++) {
            var pt = intersection(arr[i], arr[j]); //returns null if no point found
            if (pt != null) {
                ellipse(pt.x, pt.y, 30, 30);
            }
        }
    }
}
 
//helper function to change the color slightly for the lines each time
function shiftColor(x) {
    x = x + random(-50, 50);
    return (x <= 255 ? x : 255);
}
 
//uses Paul Bourke's formula @ http://paulbourke.net/geometry/pointlineplane/
function intersection(line1, line2) {
    var x1 = line1.x;
    var x2 = line1.x + globalMag * line1.vec.x;
    var x3 = line2.x;
    var x4 = line2.x + globalMag * line2.vec.x;
    var y1 = line1.y;
    var y2 = line1.y + globalMag * line1.vec.y;
    var y3 = line2.y;
    var y4 = line2.y + globalMag * line2.vec.y;
    var ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
    var x = x1 + ua * (x2 - x1);
    var y = y1 + ua * (y2 - y1);
    var x1points = (x1 <= x2) ? [x1, x2] : [x2, x1];
    var x2points = (x3 <= x4) ? [x3, x4] : [x4, x3];
 
    return ((x1points[0] <= x && x <= x1points[1]) &&
        (x2points[0] <= x && x <= x2points[1])) ? new Point(x, y) : null;
}
 
//basic classes
class Line {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        this.vec = p5.Vector.random2D();
    }
}
class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}