Project Title
World of Vogue – Jaidyn Perry – Professor Eric Parren
Conception and Design
The concept of this project is to expand the reach of vogue and ballroom culture to a wider audience. During my preparatory research, I learned about the ballroom scene of the early 20th century, an LGBT subculture that began in New York City and has since continued to provide a safe space for queer expression. One of the biggest parts of ballroom culture is voguing, a dance that utilizes poses often seen in high fashion to tell stories and make statements. My design was influenced by creating an interactive project that not only brings awareness of vogue to people outside the LGBT community, but to allow them to experience it for themselves. Music was something I wanted to include from the beginning, so I used a distance sensor to have the music begin once the person was within range of the sensor. I knew the biggest part of this project was getting people to follow the poses, so I focused on making a project that guides people to participate. I decided to create some guides that I could place over the capture of my webcam in processing. Referenced from some common voguing poses, I used my iPad to draw the guides and give them a transparent background. I created 9 poses in total. Below is an animated cycle through all 9 images.
During the user testing session, the cycle through worked as I had planned, it let people to follow the poses with little instruction. However, I had the camera capture mirrored because I was unsure how to fix it. I got mixed responses from this, some said they liked the challenge and others said it annoyed them. From this, I got the idea to create an intro sequence to allow people to choose if they would like their image mirrored or not, labeled easy and hard. I also was told to add some sort of image capture to capture people’s poses, so I added this as well. I believe both of these adaptations effectively made my project more interactive and more enjoyable.
Fabrication and Production
From the beginning I had planned to make a large project, but I had to scale down some after discussing with Professor Andy and realizing the tables would add height, so I could focus on making a well-structured and nice looking project. I used the woodshop in the fabrication lab to create the project, building a large wooden structure with holes for a monitor and speaker, as well as adding hinges to support the wooden panels and allow them to bend for easier movement of the project.
I believe that my construction of the project as a whole was successful, but I had tried to 3D print a box to hold the wires, buttons and distance sensor and failed.
I did not think about the fact that having the buttons stand up on the breadboard would be unstable, and using the box made the buttons impossible to press without them coming out of the breadboard entirely. I should have used f/m wires to connect the buttons and have them against the table. The issue of not having something to cover the buttons and sensors as well as having the buttons stand up on the breadboard became big problems as people tested it and the wires became unstable and the connection would falter leading to the music especially not working. I unfortunately did not realize this until after the presentation of my project, and I think if I had made a prototype of this small box and brought it to the user testing, I could have found the issue and fixed it before it became a problem.
I think the choice of sensors and buttons for my project was the most appropriate because the focus of the project was on the Processing code and screen display. I had considered using a light sensor as well, but I figured that it would not have a place within the project as I wanted people to be immersed in their experience with the poses.
Conclusions
The goals of my project were to create an immersive experience to become aware of vogue and learn some common poses. I do believe my project accomplished these goals, but I think I could have been more successful in expressing what vogue is and why it is significant. I had many people think the project was in reference to an anime, and I think that is because vogue is not well known outside of the LGBT community. I think since I wanted to bring awareness into the project, I should have put more thought into how to explain what it is. However, as an experience I think it was very successful. I had many people eager to participate in the project during the IMA show, and I was happy to see everyone having fun with it. My results align with my definition of interaction because through the sensor and the buttons, the project takes input from the user and changes the experience based on those inputs. If I had more time, I would like to add some tracking where people’s positions could be monitored and then change the scene. If I did that, it would also allow for a scoring system and more direct interaction. I would also add more music. I had an entire playlist of songs that I wanted to incorporate, but I could only figure out how to code one song into the project. From my setbacks and failures I have learned the importance of creating prototypes for the entire project, not just certain parts, and to think everything through in its entirety. From my accomplishments, I take away the value of providing an engaging experience for people of all ages and how much putting time and detail into presentation adds to a project. The importance of my ideas is to bring the importance and cultural significance of vogue outside of the ballroom and show others how to participate in and enjoy this part of LGBT history. It is important to demonstrate how essential ballroom and vogue are, and have been for decades, to the LGBT community. Creating this project allowed me to become more in touch with the history and representation of my community, and show others the beauty of queer history and joy.
Appendix
Disclaimer : I have permission from those in the media to use the photos and videos provided
I give my appreciation to Professors Gottfried, Eric, and Andy as well as the IMA fellows and Interaction Lab Learning Assistants for their help with code and fabrication.
The Arduino and Processing Reference websites were also utilized.
Code:
Arduino :
const int buttonPin = 2; // hard
const int button2Pin = 4; // easy
#include <Mouse.h>
const int trigpin = 8;
const int echopin = 7;
long duration;
int distance;
int mirrorState = 2;
int buttonState = 0;
int button2State = 0;
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(button2Pin, INPUT);
pinMode(trigpin, OUTPUT);
pinMode(echopin, INPUT);
}
void loop() {
// to send values to Processing assign the values you want to send
// this is an example:
buttonState = digitalRead(buttonPin);
button2State = digitalRead(button2Pin);
// if (buttonState == HIGH) {
// mirrorState = 0;
// } else if (button2State == HIGH) {
// mirrorState = 1;
// }
digitalWrite(trigpin, HIGH);
delayMicroseconds(10);
digitalWrite(trigpin, LOW);
duration = pulseIn(echopin, HIGH);
distance = duration * 0.034 / 2;
// send the values keeping this format
Serial.print(buttonState);
Serial.print(","); // put comma between sensor values
Serial.print(button2State);
Serial.print(","); // add linefeed after sending the last sensor value
Serial.print(distance);
// Serial.print(",");
// Serial.print(mirrorState);
Serial.println();
// too fast communication might cause some latency in Processing
// this delay resolves the issue
delay(10);
// end of example sending values
}
Processing:
import processing.video.*;
import processing.sound.*;
import processing.serial.*;
// arduino
//import processing.serial.*;
SoundFile Mother;
SoundFile Cheer;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 3; /* CHANGE THIS ACCORDING TO YOUR PROJECT */
/* This array stores values from Arduino */
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
// video
int sceneIndex = 0;
int w = 1330;
int h = 770;
int i = 0;
Capture camDevice;
PImage overlay;
int savedTime;
int totalTime = 6000;
int mirrorState = 2;
void setup() {
size(1330, 770);
savedTime = millis();
serialPort = new Serial(this, "/dev/cu.usbmodem1401", 9600);
camDevice = new Capture(this, w, h);
camDevice.start();
Mother = new SoundFile(this, "Mother.mp3");
Cheer = new SoundFile(this, "Cheer.mp3");
// nailsHair.loop();
drawIntro();
}
void draw() {
println(sceneIndex);
getSerialData();
if (mirrorState != 2) {
if (arduino_values[2] <= 40) {
Mother.loop();
}
// rec();
// update(mouseX, mouseY);
//if (arduino_values[0] == 1) {
// nextScene();
// delay(20);
//}
//if (arduino_values[1] == 1) {
// previousScene();
// delay(20);
//}
int passedTime = millis() - savedTime;
if (passedTime > totalTime && sceneIndex >= 0) {
println("6 seconds have passed!");
nextScene();
savedTime = millis(); // Save the current time to restart the timer!
}
if (sceneIndex == 0) {
drawScene9();
} else if (sceneIndex == 1) {
drawScene1();
} else if (sceneIndex == 2) {
drawScene2();
} else if (sceneIndex == 3) {
drawScene3();
} else if (sceneIndex == 4) {
drawScene4();
} else if (sceneIndex == 5) {
drawScene5();
} else if (sceneIndex == 6) {
drawScene6();
} else if (sceneIndex == 7) {
drawScene7();
} else if (sceneIndex == 8) {
drawScene8();
} else if (sceneIndex == 9){
drawEnding();
Cheer.loop();
}
} else {
savedTime = millis();
drawIntro();
if (arduino_values[0] == 1) {
mirrorState = 0;
} else if (arduino_values[1] == 1) {
mirrorState = 1;
}
}
}
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII
if (in != null) {
//print("From Arduino: " + in);
String[] serialInArray = split(trim(in), ",");
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}
void mousePressed() {
if (mouseX < width / 2) {
previousScene();
} else {
nextScene();
}
}
void previousScene() {
sceneIndex--;
if (sceneIndex < 0) {
sceneIndex = 9;
}
}
void nextScene() {
sceneIndex = (sceneIndex + 1) % 9;
}
void keyPressed() {
saveFrame();
}
void drawIntro() {
background(0);
overlay = loadImage("DrawIntro.jpg");
image(overlay, 0, 0, width, height);
}
void drawScene1() {
overlay = loadImage("pGuide-1.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene2() {
overlay = loadImage("pGuide-2.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene3() {
overlay = loadImage("pGuide-3.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene4() {
overlay = loadImage("pGuide-4.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene5() {
overlay = loadImage("pGuide-5.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene6() {
overlay = loadImage("pGuide-6.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene7() {
overlay = loadImage("pGuide-7.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene8() {
overlay = loadImage("pGuide-8.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawScene9() {
overlay = loadImage("pGuide-9.png");
if (camDevice.available() == true) {
camDevice.read();
}
tint(255, 127);
pushMatrix();
if (mirrorState == 1) {
translate(width, 0);
scale(-1, 1);
} else {
scale(1, 1);
}
image(camDevice, 0, 0);
popMatrix();
image(overlay, 0, 0, width, height);
}
void drawEnding() {
background(0);
overlay = loadImage("End.jpg");
image(overlay, 0, 0, width, height);
}