Project 3 – Dynamic Drawing

Controls:
– upper right corner = scale up
– lower left corner = scale down
– up & down = triangles move to the right
– click & hold on triangle = rotate
– hover over triangle = fade to white

Originally I wanted to make a field of triangles, where the triangle & neighboring triangles would flip out into a ripple. Initial generation of the triangular grid was easy, but when I wanted to proceed with more complicated maneuvers, I found my self going back to and rewriting my code so it was more structured and centralizing all the important parameters I wanted my operations to depend on.


In particular, I really struggled with the rotation implementation. P5’s scale operation acts as a blanket technique, operating on all the geometries called after it, whereas I wanted triangles to rotate individually, meaning I had to parse through every single triangle individually to find the one I wanted to rotate. When rotating, wiggling the mouse causes the rotation to flicker, as the file is looping through draw to update the new mouse position, so keeping the mouse still when rotating pieces is advised. The rest were relatively straightforward to implement.

sketch
// Tsz Wing Clover Chau
// Section E


function setup() {
    createCanvas(600, 600);
    background(220);
    text("p5.js vers 0.9.0 test.", 10, 15);
    frameRate(200);
}

var init = true;

var row = 0;
var col = 0;
var selCol = 0;
var selRow = 0;

var offset = 30;

var n = 3;
var l = 0;


var leftX = 0;
var rightX = 0;
var ptX = 0;
var leftY = 0;
var rightY = 0;
var ptY = 0;

var mX = 0;
var mY = 0;

var wait = 70;

var sizeCounter = 1;


let neighC = [255, 255, 255];

let triList = [];


function area(x1, y1, x2, y2, x3, y3) {
    return abs(((x1*(y2-y3)) + (x2*(y3-y1))+ (x3*(y1-y2)))/2);
}

function inbounds(x1, y1, x2, y2, x3, y3, mouseX, mouseY){
    let A = area(x1, y1, x2, y2, x3, y3);
    let A1 = area(mouseX, mouseY, x2, y2, x3, y3);
    let A2 = area(x1, y1, mouseX, mouseY, x3, y3);
    let A3 = area(x1, y1, x2, y2, mouseX, mouseY);
    return (A == A1+A2+A3);
}



function draw() {
    noStroke();
    background(220);
    
    l = (width-(offset*(n-1)))/n;
    var h = sqrt(3)/2 * l; 

    // init triangle grid
    if (init){
        if (row %4 == 0){
            leftX = (col*(l+offset)) + offset;
            rightX = leftX + l;
            ptX = leftX + l/2;

            leftY = (row/2*(h+offset/2)) + offset;
            rightY = leftY;
            ptY =  leftY + h;

            midY = leftY + h/2;


        } else if (row %4 == 2) {
            leftX = ((col-0.5)*(l+offset)) + offset;
            rightX = leftX + l;
            ptX = leftX + l/2;


            leftY = ((row/2)*(h+offset/2)) + offset;
            rightY = leftY;
            ptY =  leftY + h;

            midY = leftY + h/2;

        } else if (row %4 == 3) {
            leftX = ((col - 0.5)*(l+offset)) + l/2 + offset*(3/2);
            rightX = leftX + l;
            ptX = leftX + l/2;

            leftY = (int(row/2)*(h+offset/2)) + h + offset;
            rightY = leftY;
            ptY = leftY - h; 

            midY = leftY - h/2;


        } else {
            leftX = ((col-1)*(l+offset)) + l/2 + offset*(3/2);
            rightX = leftX + l;
            ptX = leftX + l/2;

            leftY = (int(row/2)*(h+offset/2)) + h + offset;
            rightY = leftY;
            ptY = leftY - h;  

            midY = leftY - h/2;
        }
        midX = ptX;

        var cShift = false;
        var a = 90;
        let selC = [0, 0, 0];

        append(triList, [leftX, leftY, rightX, rightY, ptX, ptY, selC, cShift,
                         a, midX, midY, row, col]);

    } else {

        //controlling SCALE
        if (wait == 0 & mouseX < width/8 && mouseY < height/8){
            sizeCounter += 0.01;
        } else if (sizeCounter > 1 & mouseX > width/4 && mouseY > height*3/4){
            sizeCounter -= 0.01;
            }
        scale(sizeCounter);
        
        

        for (let i = 0; i< triList.length; i++) {
            mX = mouseX;
            mY = mouseY;
            elem = triList[i];


            fill(elem[6]);

            //controlling POSITION
            if ((mouseY > elem[2] & mouseY > elem[5]) ||
                (mouseY > elem[2] && mouseY < elem[5])){
                    elem[0] -= 0.5;
                    elem[2] -= 0.5;
                    elem[4] -= 0.5;
                    elem[9] -= 0.5;
                }

            if (inbounds(elem[0], elem[1], elem[2], elem[3], 
                         elem[4], elem[5], mX, mY)) {
                elem[7] = true;

                //controlling SHADE
                if (elem[7]){
                    for (let i = 0; i< 3; i++){
                        elem[6][i] += 10;
                    }
                }
                // controlling ROTATION  (don't move mouse during rotation - it flickers)
                if (mouseIsPressed){
                    push();
                    fill(255, 255, 255);
                    translate( elem[9], elem[10]);
                    rotate(radians(elem[8]), [elem[9], elem[10], 0]);
                    translate(-elem[9], -elem[10]);
                    triangle(elem[0], elem[1], elem[2], elem[3], elem[4], elem[5]);
                    pop();

                    elem[8] += 3;
                }
            } else {
                elem[7] = false;
            }
            if (elem[8] == 90){
                triangle(elem[0], elem[1], elem[2], elem[3], elem[4], elem[5]);
            }
        }
    }


    if (col > n){
        row ++;
        col = 0;
        if (rightY +h > height) {
        init = false;
        }
    } else {
        col ++;
    }

    if (wait > 0){
        wait --;
    }
}

Leave a Reply