/* 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:
- Each circle is a sentence in the play.
- The size of the circle represents the sentence length.
- The circle sequence is according to the chronological order of sentences in the play.
- The interval between sentences is in proportion to the length of the previous sentence.
- 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.