Michal Luria – Final Project

mluria-final

/*  Submitted by: Michal Luria
    Section A: 9:00AM - 10:20AM
    mluria@andrew.cmu.edu
    Final-Project
*/

//variables to draw circles
var circles = []; //array of circle objects
var sentArray = []; //array for sentences
var posX = []; //the circle bases (character) X array
var posY = []; //the circle bases (character) Y array

//variables to determine most dominant character
var scores = []; //start with an empty array 
var currentHighest = 0; //currently most sentences
var winnerIndex; //the index of the winner
var previousWinnerIndex = -1; //the index of the previous winner 

function preload() {
    //load text to strings - each part (by character) is a string
    textArray = loadStrings('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/the-miser.txt'); 

}

function setup () {

    createCanvas(700,500);
    frameRate(30);

    //determine initial positions of characters
    posX = [width/2, width/5, width/5*4, width/2, width/2, width/5, width/5*4]; 
    posY = [height/2, height/2, height/2, height/5, height/5*4, height/5*4, height/5];

    //initialize 0 for all scores
    for (var k = 0; k < posX.length; k++){

        scores[k] = 0;

    }

    //for every paragraph in the file (one string), split into sentences
    for (var i = 0; i < textArray.length; i++){ 

        //split sentences whenever one of the following chars appear: ;!?.
        sentArray = splitTokens(textArray[i], ";!?.");


        //The following code will do this: for every sentence a character says, create a circle object and draw it

        //if VAL is talking (if the word VAL in the string)
        if (textArray[i].indexOf("VAL") >= 0) {

            //for every sentence VAL speaks, push a circle object into the circle array
            for (var j = 1; j < sentArray.length; j++) {

                /*pass the following variables for each circle object: 
                                        name
                                        length of sentence (the size of the circle is determined by how long the sentence is)
                                        Start frame - each circle has a frame number on which it can start drawing (using FrameCount)
                                                      The start frame is influenced by the index of the play sentences (how far is
                                                      the sentence into the play [i]), by the current index [j], and by the
                                                      length of the previous sentence, in order to give a feel of the play dynamics
                                        Color
                                        Index number
                                        */
                circles.push(new Circle("VAL", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(247, 132, 163, 80), 0));
            }   

        }

        //The above comments are true for each one of the characters in the play below:

        //if ELI is talking (found in string)
        if (textArray[i].indexOf("ELI") >= 0) {

            //for every sentence ELI speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("ELI", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(132, 247, 159, 80), 1));
            }

        }

        //if CLE is talking (found in string)
        if (textArray[i].indexOf("CLE") >= 0) {

            //for every sentence CLE speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("CLE", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(132, 194, 247, 80), 2));
            }

        }

        //if HAR is talking (found in string)
        if (textArray[i].indexOf("HAR") >= 0) {

            //for every sentence HAR speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("HAR", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(255, 246, 100, 80), 3));
            }

        }

        //if LA FL is talking (found in string)
        if (textArray[i].indexOf("LA FL") >= 0) {

            //for every sentence LA FL speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("LA FL", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(205, 139, 255, 80), 4));
            }

        }


        //if SIM is talking (found in string)
        if (textArray[i].indexOf("SIM") >= 0) {

            //for every sentence SIM speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("SIM", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(133, 251, 255, 80), 5));
            }

        }

        //if FRO is talking (found in string)
        if (textArray[i].indexOf("FRO") >= 0) {

            //for every sentence FRO speaks, push a circle onject into array
            for (var j = 1; j < sentArray.length; j++) {

                circles.push(new Circle("FRO", sentArray[j].length, 
                                        j*i*20+(sentArray[j-1].length*2), color(255, 133, 255, 80), 6));
            }

        }

    }

}


function draw () {

    background(0);
    stroke(0);

    //draw all circle objects
    for (var i = 0; i < circles.length; i++){

        circles[i].draw();

    }

    //The follow section checks who the most dominant character (winner) is and updates their location

    //check all the scores all the time (score = number of sentences a character said)
    for (var j = 0; j < scores.length; j++){

        //if a score is higher the current highest score
        if (scores[j] > currentHighest) {

            currentHighest = scores[j]; //update highest score

            if (j != winnerIndex) { //if the highest score holder (character) changed

                previousWinnerIndex = winnerIndex; //update the previous winner category
                winnerIndex = j; //and update the new winner

            }


        }
    }

    /*Update the winner's location
    The following parts check where the winner is, and move them towards the center
    In parallel, the previous winner is moved in the opposite direction of the winner
    in order to switch between their locations */


    if (posX[winnerIndex] < width/2) {
        posX[winnerIndex]++; 
        posX[previousWinnerIndex]--; 
    }


    if (posY[winnerIndex] < height/2) {
        posY[winnerIndex]++;
        posY[previousWinnerIndex]--;
    }

    if (posX[winnerIndex] > width/2) {
        posX[winnerIndex]--;
        posX[previousWinnerIndex]++;
    }

    if (posY[winnerIndex] > height/2){
        posY[winnerIndex]--;
        posY[previousWinner]++;
    }

}

//define circle object: name, sentence array, start frame, color and index
function Circle(name, sentArray, 
     myStartFrame, circColor, index) {

    this.name = name; //name of actor
    this.sent = sentArray; //length of sentence
    this.index = index; // index of character
    this.x = posX[this.index]; //circle X location
    this.y = posY[this.index]; //circle Y location
    this.siz = 0; //circle Size
    this.start = myStartFrame; //the frame to start drawing the circle
    this.color = circColor; //the color of the circle
 

    this.draw = function() { //draw a circle

        noStroke();


  
        fill(this.color); //use the object's circle

        /*determine circle size by sentence length (as long as the size is smaller than the sentence length * 2.5)
        and only if the current frame count is bigger than the object's start frame
        draw the circle*/
        if (this.siz < this.sent * 2.5 & frameCount > this.start) {
            
            this.x = posX[this.index]; //update the x position according to winner check
            this.y = posY[this.index]; //update the y position according to winner check
            ellipse (this.x, this.y, this.siz, this.siz); //draw the circle
            this.siz++; //increase circle size
            scores[this.index]++; //increase the score count for the character for each of his/her sentence circle 

            //write the name of the character below (also shows up and disappears according to the character on stage)
            textSize(10); 
            text(this.name, this.index*100+40, height-50);

        } 

    }

}

The Miser / Moliere

In my final project I wanted to do data visualization. With a background in theater, I thought it would be interesting to look at plays and show new aspects by using their data.

I used the famous play “The Miser” by Moliere, and created several aspects that would allow viewers to get a sense of the play dynamics.

Description of what you see: 

  1. Each circle is a sentence in the play.
  2. The size of the circle represents the sentence length.
  3. The circle sequence is according to the chronological order of sentences in the play.
  4. The interval between sentences is in proportion to the length of the previous sentence.
  5. The most dominant character in each part of the play is centered in location.

My final project visualized each sentence by a character in the play using a circle, “played” in the order of the characters text. The size of each circle visualizes the length of the sentence. The project also presents who is on stage at every given moment, and finally, the character that is most dominant in the play comes to the center of the stage.

I hope that using these aspects, it will be easy to get a sense of the pace of the play, if the dialog is quick or slow, who talks a lot and who is more quiet, when monologs occur, and who dominates the play dynamics. I hope that the visualization will allow looking at a famous masterpiece in a new light.

Leave a Reply