Return to Main Page
Krista's notes for meeting of 12 Nov 2008
-
Portray the heart as a mechanical object, but the rest of the body as flesh and blood. Metallic model of the heart, moving parts in the heart.
-
Possibility of putting ardino in heart and connecting it to a screen reacting to movement. Heart placed in some kind of flesh body. Clock based gears.
-
Circulation system inclusion possibility—use of piping as valves.
Feedback
-
what mechanical would have meant to Harvey—clockwork mechanism in mind, but he is talking about a fluid mechanical system that is not at all gear like.
-
more movement in gears direction.
-
video of how a real heart works, and a model which people can play with that highlight Harvey's ideas.
-
problem of projecting our version of mechanical on the past—Descartes idea of mechanical.
Feedback from 14 Jan 2009 meeting
-possibility of cutting nerf ball apart. —those near dollar store to look for cheap toys to test out.
-sensitivity levels, one side is stronger than the other.
-testing different heart shaped squeezeable interfaces
-hard outside, squishy stuff on the inside—material heart
-discussion of including the heart in a representation of the body.
Feedback from 28 Jan 2009 Meeting
-Problem of finding a foam ball addressed, this will eventually be turned into a more sophisticated model.
-Thicker foam on one side to deal with pressure.
-Slow vs. fast heart beat appearing on screen.
-Need to make sure that everyone in the group has something to work on, speak up if you feel you need more or less to do!
Notes - Group Presentation - 25 February 2009
-add a tactile element to the heart, a pager modem
-if possible make one button harder to push, harder foam or tighter spring
-aid to simulate the heartbeat
-add sound effect, when the heart dies
-include a flashier graph for the heart beat
-make the model more 3-D
-suggested sign "Keep it Alive"
-record or track the highest score
-consider the take away message, Harvey learned by experimentation
-suggested sign "Save the Heart."
Lois's notes.
Foam Heart
Sample Code for Arduino
/////////////////////////////////////////////////////////////////////////////////////
// Program to track user inputs for a heart simulation
// Two FSRs are attached to pins 2 and 3 of the arduino
// when a FSR is pressed it triggers an interrupt for its respective pin
// the interrupts compare the timing and order of the FSR presses
// either a successful beat or error code is outputed depending on input
/////////////////////////////////////////////////////////////////////
/// Declare Variables and Constants
int SENSORPIN_1 = 2; // select the input pin for 1st sensor
int SENSORPIN_2 = 3; // select the input pin for 2nd sensor
int MOTORPIN_1 = 8; // select the output pin for 1st motor
int MOTORPIN_2 = 9; // select the output pin for 2nd motor
volatile boolean SENSOR1_PRESS = false; //Track if sensor sucessfully pressed
volatile float SENSOR1_TIME = 0 ; //Record time of sensor 1 pressed
volatile float SENSOR2_TIME = 0 ; //Record time of sensor 2 pressed
volatile float SPIKE_TIME=300; //time for spikes on sensor (ms)
volatile float BEAT_LOW = 750; //Low end of range for time length of a good beat
volatile float BEAT_HIGH = 1500; //High end of range for time length of a good beat
///////////////////////////////////////////////////////////////////////
///Setup Arduino
void setup() {
pinMode(SENSORPIN_1, INPUT); // declare the sensor pin 1 as input
pinMode(SENSORPIN_2, INPUT); // declare the sensor pin 2 as input
pinMode(MOTORPIN_1, OUTPUT); // declare the motor pin 1 as output
pinMode(MOTORPIN_2, OUTPUT); // declare the motor pin 2 as output
Serial.begin(9600); //turn on serial Port
attachInterrupt(0, SENSOR1_ISR, RISING); //Create an interrupt in pin 2 for sensor 1 on rising edge
attachInterrupt(1, SENSOR2_ISR, RISING); //Create an interrupt in pin 3 for sensor 2 on rising edge
}
///////////////////////////////////////////////////////////////////////
/// Main Loop
void loop() {
if (digitalRead(SENSORPIN_1)==HIGH) {
digitalWrite(MOTORPIN_1,HIGH);
}
if (digitalRead(SENSORPIN_1)==LOW) {
digitalWrite(MOTORPIN_1,LOW);
}
if (digitalRead(SENSORPIN_2)==HIGH) {
digitalWrite(MOTORPIN_2,HIGH);
}
if (digitalRead(SENSORPIN_2)==LOW) {
digitalWrite(MOTORPIN_2,LOW);
}
}
/////////////////////////////////////////////////////////
//Sensor 1 Interrupt
void SENSOR1_ISR() {
//ensure this isnt a spike triggering extra interrupts
//do so by comparing time of this interrupt with last, if it is very small it is likly a spike
if ( (millis() - SENSOR1_TIME)> SPIKE_TIME){
//Check to make sure user has not double pressed first sensor
//If They have return Error, else record press
if (SENSOR1_PRESS== true){
Serial.println("5"); //error signal
SENSOR1_PRESS= false; //reset
}
else {
SENSOR1_PRESS=true;
SENSOR1_TIME= millis();
}
}
}
/////////////////////////////////////////////////////////////////
//Sensor 2 Interrupt
void SENSOR2_ISR() {
//ensure this isnt a spike triggering extra interrupts
//do so by comparing time of this interrupt with last, if it is very small it is likly a spike
if ( (millis() - SENSOR2_TIME)> SPIKE_TIME){
SENSOR2_TIME=millis();
//Check to make Sure Sensor 1 has been pressed, if not error
if (SENSOR1_PRESS== false){
Serial.println("4"); //error signal
}
//Check to make sure time between presses isnt too fast
else if ( (SENSOR2_TIME - SENSOR1_TIME ) < BEAT_LOW) {
Serial.println("2"); //error signal
SENSOR1_PRESS= false; //reset
}
//Check to make sure time between presses isnt too slow
else if ( (SENSOR2_TIME - SENSOR1_TIME ) > BEAT_HIGH) {
Serial.println("3"); //error signal
SENSOR1_PRESS= false; //reset
}
//output a good beat
else {
Serial.println("1");
SENSOR1_PRESS= false; //reset
}
}
}
Sample Code for Processing
//import serial library
import processing.serial.*;
//create serial object
Serial sPort;
//variable to store read serial values
String Ard="0";
void setup(){
size (500,500);
String portName = "COM3";
sPort = new Serial(this, portName, 9600);
PFont font;
font=loadFont("Arial.vlw");
textFont(font);
}
void draw (){
background(90);
//If bytes sent in serial read and store in Ard
if (sPort.available()>0){
Ard=sPort.readString();
//read only first character sent, processing appends extra characters onto value from arduino
Ard=Ard.substring(0,1);
}
//Normal Beat
if (Ard.equals("1")){
DRAW_BEAT (0,250,250,250);
DRAW_BEAT (250,250,250,250);
text("--Normal Heart Beat", 90, 400);
}
//Fast Beat
else if (Ard.equals("2")){
DRAW_BEAT (0,250,100,250);
DRAW_BEAT (250,250,100,250);
line(100,250,250,250);
line(350,250,500,250);
text("--Too fast!", 90, 400);
}
//Slow Beat
else if (Ard.equals("3")){
DRAW_BEAT (0,250,250,50);
DRAW_BEAT (250,250,250,50);
text("--Too slow!", 90, 400);
}
//Dead Beat
else {
fill(220,0,0);
text("THE HEART IS DEAD", 50, 400);
}
}
////////////////////////////////////////////////////////////////////
///Function to Draw a heart beat
//This defines what the new command or function in processing is
//the function will not do anything unless it is called elsewhere in the program
//X_START is the x location of the start of the left hand side of the curve
//Y_START is the y location of the start of the left hand side of the curve
//X_SIZE defines the x size of the curve (distance from starting to point to end point)
//Y_SIZE defines the y size of the curve (distance from flat line to peak of R curve)
void DRAW_BEAT(int X_START, int Y_START, int X_SIZE, int Y_SIZE){
noFill();
beginShape();
//Starting Flatline
vertex(X_START,Y_START);
vertex(X_START+(.15*X_SIZE),Y_START);
//p-curve
curveVertex(X_START+(.15*X_SIZE),Y_START);
curveVertex(X_START+(.24*X_SIZE), Y_START-(.125*Y_SIZE));
curveVertex(X_START+(.30*X_SIZE),Y_START);
curveVertex(X_START+(.30*X_SIZE),Y_START);
//pr-segment (straight line)
vertex(X_START+(.30*X_SIZE),Y_START);
vertex(X_START+(.42*X_SIZE),Y_START);
//Q line
vertex(X_START+(.44*X_SIZE),Y_START+(.125*Y_SIZE));
//R line
vertex(X_START+(.48*X_SIZE),Y_START-Y_SIZE);
//S-line
vertex(X_START+(.51*X_SIZE),Y_START+(.3*Y_SIZE));
//ST Segment
vertex(X_START+(.55*X_SIZE),Y_START);
vertex(X_START+(.69*X_SIZE),Y_START);
//T Curve
curveVertex(X_START+(.69*X_SIZE),Y_START);
curveVertex(X_START+(.80*X_SIZE),Y_START-(.2*Y_SIZE));
curveVertex(X_START+(.87*X_SIZE),Y_START);
curveVertex(X_START+(.87*X_SIZE),Y_START);
//end flatline
vertex(X_START+(.87*X_SIZE),Y_START);
vertex(X_START+X_SIZE,Y_START);
endShape();
}
Sample Code for Processing Version 2
//////////////////////////////////////////////////////////////////////////////////////////////////////
///Reads output from Arduino, draws a heart beat appropriate for user input
/////////////////////////////////////////////////////////////////////////////////////////////////////
//Updated from previous code
//straight lines drawn with rectangles instead of ellipses allowing for faster drawing
//updated drawing method for better continuity between sections of beat curve
//import serial library
import processing.serial.*;
//create serial object
Serial sPort;
//Everything is drawn in parametric terms
float sub_curve_percent=1.1; //How far along the beat curve we have drawn, it is a percent of a percent!, global variable
float sub_sub_curve_percent=0;//How far along the subsection of the beat curve we have drawn, it is a percent of a percent of a percent!
////Global Variables
float step_size = 0.002; // How far each step travels (in percent)
float percent = 0.0; // Current Location Percent (0 -> 1)
float draw_percent=0; //holds locations to draw current heart beat
String beat_type="a"; //stores type of beat to be drawn
float clear_box_x=0; //store where to draw clear box
int beat_count=0; //Counts total number of good beats in a row
//Default sizes for different beats
float fast_size=0.175;
float normal_size=0.25;
float slow_size=0.35;
//Size of ellipse used to draw curves
float x_ellip=6;
float y_ellip=6;
//variable to store read serial values
String Ard="0";
//for translations, used to store current end of curve as it is drawn, allows origin to be easily redefined to the end of the curve
float x_trans=0;
float y_trans=0;
float x_trans_2=0;
float y_trans_2=0;
float x_trans_3=0;
float y_trans_3=0;
float x_trans_4=0;
float y_trans_4=0;
/////////////////////////////////////////////////////////////////////////////////////////////
//Void setup
void setup() {
size (900,800);
noStroke();
smooth();
//Create Serial port class
String portName = "COM3";
sPort = new Serial(this, portName, 9600);
//import font
PFont font;
font=loadFont("Arial.vlw");
textFont(font);
//Draw initial square for whole screen
fill(85);//Draw Original Square
rect(0, 0,width,height);
//Draw initial square in middle
fill(20);//Draw Original Square
rect(0, height/4,width,height/2);//Only do for middle 1/2
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////Void Draw
void draw(){
//Background at bottom and top
stroke(150,200,0);
fill(15,7);
rect(0, ((3*height)/4),width-1,(height/4)-1);
rect(0, 0,width-1,height/4);
noStroke();
//Title
textAlign(CENTER);
fill(150,200,0);
textSize(50);
text("William Harvey",width/2,height/12);
text("Mechanical Philosopher",width/2,height/6);
//Fixed Data headings
textAlign(LEFT);
fill(150,200,0);
textSize(30);
text("Previous Beat Type:", width/36 ,height/1.25);
text("Previous Error Type:", width/36 ,height/1.10);
textSize(30);
textAlign(CENTER);
text("Normal Beat Count", width/2+width/3 ,height/1.175);
textSize(45);
text(beat_count, width/2+width/3 ,height/1.10);
textAlign(LEFT);
//centre background
fill(55,7);//Draw in opaque background fading away
rect(0, height/4,width,height/2);//Only do for middle 1/2
//If bytes sent in serial read and store in Ard
if (sPort.available()>0){
Ard=sPort.readString();
//read only first character sent, processing appends extra characters onto value from arduino
Ard=Ard.substring(0,1);
}
//Give error if user attempts input while drawing a heart beat
if ((sub_curve_percent<1.0)&&(Ard.equals("a")==false)){
Ard="a";
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
fill(150,255,0);
textSize(30);
text("Misbeat", width/3, height/1.10);
beat_count=0;
}
/////////////////////////////////////////////
//decide what to do with read data, if not while another curve is being drawn
if (sub_curve_percent>=1){ //make sure nothing else is being drawn
//Config for normal beat
if (Ard.equals("1")){
draw_percent=percent;
percent=percent+normal_size;
//wrap around screen if percent greater than 1.0
if (percent>=1.0){
percent=percent-1.0;
}
beat_type="1";
Ard="a";
sub_curve_percent=0;
//clear out top/bottom part of screen
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
//write text
fill(150,200,0);
textSize(30);
text("Normal", width/3, height/1.25);
beat_count=beat_count+1;
}
//Config for fast beat
if (Ard.equals("2")){
draw_percent=percent;
percent=percent+fast_size;
//wrap around screen if percent greater than 1.0
if (percent>=1.0){
percent=percent-1.0;
}
beat_type="2";
Ard="a";
sub_curve_percent=0;
//clear out top/bottom part of screen
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
//write text
fill(150,200,0);
textSize(30);
text("Fast", width/3, height/1.25);
beat_count=0;
}
//Config for slow beat
if (Ard.equals("3")){
draw_percent=percent;
percent=percent+slow_size;
//wrap around screen if percent greater than 1.0
if (percent>=1.0){
percent=percent-1.0;
}
beat_type="3";
Ard="a";
sub_curve_percent=0;
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
fill(150,200,0);
textSize(30);
text("Slow", width/3, height/1.25);
beat_count=0;
}
//error if pressed in wrong order
if (Ard.equals("4")){
Ard="a";
//clear out bottom part of screen
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
fill(150,200,0);
textSize(30);
text("Wrong Chamber Order", width/3, height/1.10);
beat_count=0;
}
//Error if button 1 pressed twice in a row
if (Ard.equals("5")){
Ard="a";
//clear out bottom part of screen
fill(55);//Draw Original Square
rect(0, (height*3)/4,width,height/4);//Only do for bottom 1/4
fill(150,200,0);
textSize(30);
text("Double Left Chamber", width/3, height/1.10);
beat_count=0;
}
}
/////////////////////////////////////////
//////////Draw a heart beat if required
//If at the end of the screen reset
if(percent>=1.0){
percent=-0.05;
}
if (sub_curve_percent<1.0){
//Draw Normal beat
if (beat_type.equals("1")){
draw_beat(draw_percent,0.0006,normal_size,.8,1.5);
clear_box((clear_box_x+5));
//wrap around if drawing at end of screen
if ((draw_percent+(normal_size*sub_curve_percent))>=1.0){
draw_percent=-(normal_size*sub_curve_percent);
}
}
//fast beat
if (beat_type.equals("2")){
draw_beat(draw_percent,0.0006,fast_size,1.0,1);
clear_box((clear_box_x+5));
//wrap around if drawing at end of screen
if ((draw_percent+(fast_size*sub_curve_percent))>=1.0){
draw_percent=-(fast_size*sub_curve_percent);
}
}
//Slow beat
if (beat_type.equals("3")){
draw_beat(draw_percent,0.0006,slow_size,.60,2);
clear_box((clear_box_x+5));
//wrap around if drawing at end of screen
if ((draw_percent+(slow_size*sub_curve_percent))>=1.0){
draw_percent=-(slow_size*sub_curve_percent);
}
}
}
//if not drawing a beat, draw a staight line
else{
straight_line(percent);
percent=percent+step_size;
clear_box(percent*width);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Draws a box to clear screen ahead of cursor
void clear_box(float x_location){
//draw rectangle to clear out things ahead
fill(55);//Draw Original Square
rect(x_location+5, (height/4)+2,width/12,(height/2-2));//Only do for middle 1/2
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Draws a beat using as ellipse or rectangle at the specified location on the screen, all variables passed are in terms of percent
void draw_beat(float start_percent, float step_size_overall, float x_size, float y_size, float scale_factor){
float x=0; //Current X Location
float y=0; //Current Y location
float m=0; //Current slope
float step_length = 0; //distance of step in x direction, untransformed
float trans_angle=0; //Stores calculated value of rotation
float angle_distance=0; //Stores length of angled lines when needed
//calculate total number of steps within curve
float sub_step_num= ((x_size)/step_size_overall);
float sub_step_size= (1.0/sub_step_num);// initial step size
/////////////////////////////////////////////////////////////////////////////////////////
//Draw inital Flat line
if ((sub_curve_percent>=0)&&(sub_curve_percent<0.15)) {
sub_step_size=0.25/scale_factor;
x= (width)*(start_percent + (x_size*0.16*sub_sub_curve_percent));
y= (height/2);
//Draw rectangle and update current locations
fill(0,255,0);
clear_box_x=x;
rect(x-1, y-step_size*width, x_size*sub_step_size*width*.15+1, y_ellip); //shift to fill gap
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=0.15;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
///Draw P Curve
if ((sub_curve_percent>=.15)&&(sub_curve_percent<0.30)) {
sub_step_size=0.05;
x= (width)*(start_percent + 0.15*x_size + (x_size*0.15*sub_sub_curve_percent));
y= (height/2) - ((height/4)*(y_size))*(0.075*sin((PI/2)*(sub_sub_curve_percent/.5)));
//Draw ellipse and update current locations
fill(0,255,0);
clear_box_x=x;
ellipse(x, y, x_ellip, y_ellip-1);
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>1.0){
sub_curve_percent=.30;
sub_sub_curve_percent=0;
}
}
////////////////////////////////////////////////////////////////////////////////////
//////pr-segment (straight line)
if ((sub_curve_percent>=.30)&&(sub_curve_percent<0.42)) {
sub_step_size=0.125/scale_factor;
x= (width)*(start_percent + 0.29*x_size + (x_size*0.13*sub_sub_curve_percent));
y= (height/2);
//Draw rectangle and update current locations
fill(0,255,0);
clear_box_x=x;
rect(x-1, y-step_size*width, x_size*sub_step_size*width*.12+1, y_ellip); //shift to fill gap
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=.42;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//Q line
if ((sub_curve_percent>=.42)&&(sub_curve_percent<0.44)) {
sub_step_size=0.125/scale_factor;
//redefine origin using translation, at the current end of the curve to make calculating the equation of the line much easier, ie b=0 in y=mx +b
pushMatrix();
translate((width)*(start_percent + (x_size*.42))-x_ellip/2,(height/2)-y_ellip/2);
x= (width)*(start_percent + 0.42*x_size + (x_size*0.02*sub_sub_curve_percent))-((width)*(start_percent + (x_size*.42)));
y= (((height/4)*(y_size)*0.125))/((width)*(start_percent + (x_size*.44))-((width)*(start_percent + (x_size*.42))))*x;
m=(((height/4)*(y_size)*0.125))/((width)*(start_percent + (x_size*.44))-((width)*(start_percent + (x_size*.42))));
trans_angle=atan(m);
step_length= (.02*x_size*width)*sub_step_size;
angle_distance= step_length/cos(trans_angle);
rotate(trans_angle);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x/cos(trans_angle), -(y_ellip)/2, angle_distance, y_ellip);
popMatrix();
x_trans=x+(width)*(start_percent + (x_size*.42))-x_ellip/2;
y_trans=y+(height/2)-y_ellip/2;
clear_box_x=x_trans;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=.44;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//R line
if ((sub_curve_percent>=.44)&&(sub_curve_percent<0.48)) {
sub_step_size=0.125/scale_factor;
//redefine origin using translation, at the current end of the curve to make calculating the equation of the line much easier, ie b=0 in y=mx +b
pushMatrix();
translate(x_trans,y_trans);
x= (width)*(start_percent + 0.44*x_size + (x_size*0.04*sub_sub_curve_percent))-((width)*(start_percent + (x_size*.44)));
y= -(((height/4)*(y_size)*1))/((width)*(start_percent + (x_size*.48))-((width)*(start_percent + (x_size*.44))))*x;
m= -(((height/4)*(y_size)*1))/((width)*(start_percent + (x_size*.48))-((width)*(start_percent + (x_size*.44))));
trans_angle=atan(m);
step_length= (.04*x_size*width)*sub_step_size;
angle_distance= step_length/cos(trans_angle);
rotate(trans_angle);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x/cos(trans_angle), -(y_ellip)/2, angle_distance, y_ellip);
popMatrix();
x_trans_2=x+x_trans;
y_trans_2=y+y_trans;
clear_box_x=x_trans_2;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=.48;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//S line
if ((sub_curve_percent>=.48)&&(sub_curve_percent<0.51)) {
//Need smaller step size to draw
sub_step_size=0.125/scale_factor;
//redefine origin using translation, at the current end of the curve to make calculating the equation of the line much easier, ie b=0 in y=mx +b
pushMatrix();
translate(x_trans_2,y_trans_2-y_ellip);
x= (width)*(start_percent + (0.48*x_size + (x_size*0.03*sub_sub_curve_percent)))-((width)*(start_percent + (x_size*.48)));
y= (((height/4)*(y_size)*1.3))/((width)*(start_percent + (x_size*.51))-((width)*(start_percent + (x_size*.48))))*x;
m=(((height/4)*(y_size)*1.3))/((width)*(start_percent + (x_size*.51))-((width)*(start_percent + (x_size*.48))));
trans_angle=atan(m);
step_length= (.03*x_size*width)*sub_step_size;
angle_distance= step_length/cos(trans_angle);
rotate(trans_angle);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x/cos(trans_angle), -(y_ellip)/2, angle_distance, y_ellip);
popMatrix();
x_trans_3=x+x_trans_2;
y_trans_3=y+y_trans_2;
clear_box_x=x_trans_3;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=.51;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//S line back up
if ((sub_curve_percent>=.51)&&(sub_curve_percent<0.55)) {
//Need smaller step size to draw
sub_step_size=0.125/scale_factor;
//redefine origin using translation, at the current end of the curve to make calculating the equation of the line much easier, ie b=0 in y=mx +b
pushMatrix();
translate(x_trans_3,y_trans_3);
x= (width)*(start_percent + (0.51*x_size + (x_size*0.04*sub_sub_curve_percent)))-((width)*(start_percent + (x_size*.51)));
y= -(y_trans_3-(height/2))/((width)*(start_percent + (x_size*.55))-((width)*(start_percent + (x_size*.51))))*x;
m=-(y_trans_3-(height/2))/((width)*(start_percent + (x_size*.55))-((width)*(start_percent + (x_size*.51))));
trans_angle=atan(m);
step_length= (.04*x_size*width)*sub_step_size;
angle_distance= step_length/cos(trans_angle);
rotate(trans_angle);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x/cos(trans_angle), (-y_ellip/2), angle_distance, y_ellip);
popMatrix();
clear_box_x=x+x_trans_3;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=.95){
sub_curve_percent=.55;
sub_sub_curve_percent=0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//ST segment
if ((sub_curve_percent>=.55)&&(sub_curve_percent<0.69)) {
sub_step_size=0.125/scale_factor;
//redefine origin using translation, at the current end of the curve to make calculating the equation of the line much easier, ie b=0 in y=mx +b
x=(width)*(start_percent + 0.55*x_size + (x_size*0.14*sub_sub_curve_percent));
y= (height/2);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x-x_ellip, y-step_size*width,x_size*sub_step_size*width*.12+x_ellip, y_ellip); //added small shift to fill in meetings of lines
clear_box_x=x;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=.69;
sub_sub_curve_percent=0.0;
}
}
/////////////////////////////////////////////////////////////////////////////////////
//T Curve
if ((sub_curve_percent>=.69)&&(sub_curve_percent<0.87)) {
sub_step_size=0.05;
x= (width)*(start_percent + 0.69*x_size + (x_size*0.18*sub_sub_curve_percent));
y= (height/2) - ((height/4)*(y_size))*(0.09*sin((PI/2)*((sub_sub_curve_percent/.5))));
//Draw ellipse and update current locations
fill(0,255,0);
ellipse(x, y, x_ellip, y_ellip);
clear_box_x=x;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.05){
sub_curve_percent=.87;
sub_sub_curve_percent=.05;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//Draw end Flat line
if ((sub_curve_percent>=.87)&&(sub_curve_percent<1.0)) {
sub_step_size=0.125/scale_factor;
x= (width)*(start_percent + 0.86*x_size + (x_size*0.14*sub_sub_curve_percent));
y= (height/2);
//Draw rectangle and update current locations
fill(0,255,0);
rect(x-1, y-step_size*width, x_size*sub_step_size*width*.12+1, y_ellip);
clear_box_x=x;
//stitch curve together
sub_sub_curve_percent=sub_sub_curve_percent+sub_step_size; //update draw location
if (sub_sub_curve_percent>=1.0){
sub_curve_percent=1.0;
sub_sub_curve_percent=0;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Draws a straight line by drawing an ellipse at the specified location on the screen
void straight_line(float current_percent){
float x=0; //Current X Location
float y=0; //Current Y location
x = (percent * width);
y = (height/2);
fill(0,255,0);
rect(x-1, y-step_size*width, step_size*width+1, y_ellip);
}

