Wednesday, 14 November 2012

Touch and Go out on Amazon/Resting this blog for now...

Resting this blog for now...


Touch and Go is now available on Amazon, Jonathan and Irini have done a brilliant job - it looks beautiful, my paper has a  lot of colour images, which makes reading it a lot less tedious.
http://www.amazon.co.uk/Leonardo-Electronic-Almanac-Vol-No/dp/1906897182/ref=sr_1_1?ie=UTF8&qid=1352891656&sr=8-1
You can get fee pdfs of all the papers here:
http://www.leoalmanac.org/vol18-no3-touch-and-go/

Saturday, 29 September 2012

Interactive Hypotrochoid


I've just written an Interactive Hypotrochoid program to play with here:

http://www.dareinteractive.com/hypo/index.html

Looks like this:



Code:



/**
 Dare 2012 Interactive Hypotrochoids, 
 move mouse around to experiment with the
 parameters of this equation, press mouse to re-set.
 very much derived from Archim v2.1
 code here:
 http://www.archimy.com/examples/2d-ellipse.html
 **/

//z must be zero
float z = 0.0;

//t-parameter
float tmin = 0.0;
float tmax = 3.0*PI;//6.0*PI;
float tgrid =120.0;//400.0;

//Constant
float a;// = 5.0;
float b;// = 3.0;
float d;// = 5.0;
float k, m;

void setup() {
  size(600, 600);
  background(0);
}

void draw() {

  translate(width/2, height/2);
  tmin++;
  tmax++;

  a = mouseX%width/3;
  d = mouseX%height/3;
  b = d/6;
  k = a - b;
  m = (a - b) / b;

  //Calculations
  float x = k * cos(tmin) + d * cos(m * tmin);
  float y = k * sin(tmax) - d * sin(m * tmax);
  noStroke();
  fill(120+mouseY%255, mouseY%255, 120+mouseX%255, 220);
  ellipse(x, y, 5, 5);
}

void mousePressed() {
  setup();
}



Hypotrochoids again

Hypotrochoid is a curve traced by a point attached to a circle of radius r rolling around the inside of a fixed circle of radius R, where the point is a distance d from the center of the interior circle...








Processing code:

/**
 adapted from some 

Archim v2.1

code here:
 http://www.archimy.com/examples/2d-ellipse.html

 change a, b, d for dramatic changes in scale, try
 float a = 5.0; //5.0 original values
 float b = 3.0;//3.0
 float d = 5.0;//5.0

 try:
 float a = 15.0*2; //5.0
 float b = 1.0*2;//3.0
 float d = 15.0*2;//5.0

 */
//z must be zero
float z = 0.0;

//t-parameter
float tmin = 0.0;
float tmax = 6.0*PI;//6.0*PI; /*try differant values here */
float tgrid = 400.0;//400.0;

/*Constants, affect scale and form hugely */
float a = 70.0; //5.0
float b =  -6.0;//3.0
float d = 70.0;//5.0
float k, m;

void setup() {
  size(500, 500);
  background(0);
}

void draw() {

  translate(width/2, height/2);
  tmin++;
  tmax++;
  k = a - b;
  m = (a - b) / b;

  //Calculations
  float x = k * cos(tmin) + d * cos(m * tmin);
  float y = k * sin(tmax) - d * sin(m * tmax);
  noStroke();
  fill(123, 0, 255, 120);
  ellipse(x, y, 12, 12);
}



This site here provided some code in Archim v2.1 which I adapted for Processing and experimented with the parameters of the equation:  
http://www.archimy.com/examples/2d-hypotrochoid.html

Sunday, 16 September 2012

Prism installation V&A

Amongst these visualisations projected onto Keiichi Matsuda's prism structure is one of mine for air quality in London. The installation is inside the tallest cupola of the V&A. there was a nice photo of it on the BBC News website yesterday.



Monday, 3 September 2012

Last variation

Last variation on the forthcoming Prism designs I hope, Sulphur Dioxide, Ozone and Nitrogen Dioxide levels in central London

Monday, 27 August 2012


Introduction to Skype Code and Shouting, Shabina Aslam and Eleanor Dare

Sunday, 26 August 2012

Blood-Sugar Roulette


25th of August, Sydenham Hill Woods, one and only performance of Blood-Sugar Roulette


Above, you can see the Hypotrochoid shapes on the ground


Above, 'Krista's' foot. Our only audience was a stranger with a black dog...


Thursday, 19 July 2012

Exposure to green and mood: peaks and lows correlated to green exposure....


LOW: Streatham High Road green average: 144



HIGH: Dulwich Woods green average: 161

Obviously loads of faults in this methodology, which is unavoidably (and un-apologetically) subjective.





//peakand low  moments green average
//map later to a chart
int average;
PImage woods;
//get averages for green chanel from images taken during day
//to see if exposure to green correlates to mood


float a =0;
void setup() {
  size(304, 163);
  woods = loadImage("woods.jpg");//161
  // woods = loadImage("highrd.jpg"); //144
  /*interesting the percieved greeness and actual greeness*/
}




void draw() {
  noLoop();
  noStroke();
  image(woods, 0, 0, width, height);
  //test with pure colours:
  //fill(255, 125, 123);
  //fill(0, 255, 0);//pure green
  // rect(0, 0, width, height);


  loadPixels();
  // Begin our loop for every pixel
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++ ) {


      int loc = x + y*width;
      float g = green (pixels[loc]);
      color c =  pixels[loc];


      a +=g;
    }
  }
  updatePixels();


  filter(BLUR, 5); //prefer blur, is like my everyday vision!
  float b = height*width;
  average = floor(a/b);
  //  println(floor(a/b)); //average greenness
  Date d = new Date();
  save(average+"*"+d+".jpg");
}

Wednesday, 18 July 2012

Improved visualisation of GPS elevation data

Improved visualisation of GPS elevation data from bike-rides around South London:



Uses curveVertex instead of lines, nicer I think....the above is Streatham to New Cross...


code below:



/*visualises the elevation data from a .gpx file
 the data is 'cleaned' in my other programs.
 Dare 2012
 */


float[] as, lon, lat;
float x, y;
int index;
ArrayList thatXPos = new ArrayList(); //array for X
ArrayList thatYPos = new ArrayList(); //array for Y
//y in this case is elevation data
float lonMax, lonMin, latMax, latMin; //to be our min and max values


void setup() {
  size(258, 320);
  as = float(loadStrings("cleanfile.txt"));
  /*create this file in 'convertGPS.pde */
  background(0);


}




void draw() {
  background(0);

  ///you might have to adjust start and ends but this seems to work
  for (int i =0;i<as.length-2;i+=2) { //all the longitude every 3rd
    thatXPos.add(as[i]); //not used in thisversion


  ///you might have to adjust start and ends but this seems to work
  for (int i =1;i<as.length-1;i+=2) { //all the  Y latitude
    thatYPos.add(as[i]); //in this case elevation data
  }




  int len = thatXPos.size();
  int len2 = thatYPos.size();
  Float[] fa = new Float[len];
  Float[] fa2 = new Float[len2];
  float[] xPosCount = new float[len];
  float[] yPosCount = new float[len2];
  thatXPos.toArray(fa);
  thatYPos.toArray(fa2);




  for (int i =0;i< len; i++) {


    xPosCount[i] = fa[i];
  } 


  for (int i =0;i< len2; i++) {


    yPosCount[i] = fa2[i];
  } 






  lonMax =max(xPosCount);
  lonMin =min(xPosCount);


  latMax =max(yPosCount);
  latMin =min(yPosCount);




  beginShape();
  for (int index =0;index<len;index++) {
    x =xPosCount[index];
    y =yPosCount[index];




    //use the minimums and maximums to calculate map()
    float x1= map(x, lonMin, lonMax, 50, width-50);
    float y2= map(y, latMin, latMax, 20, height);






    stroke(#EDFF03);
    strokeWeight(3);
    fill(#55C127);
    curveVertex(index*5, y2); //smoother than vertex
    //  vertex(index*5, y2); //less smooth
  }
  endShape();
  fill(255);
  smooth();
  // text("Elevations of cycle ride: 18/07/12", 20,30);
}




void mousePressed() {


  save("elevation.gif");
}
//end

Tuesday, 17 July 2012

Draw GPS elevation data

The ups and downs of my bike ride to Goldsmiths visualised in Processing, I generated the GPS data here: 
http://www.geoplaner.com/    
a very useful site. My code below:



/*put the text file generated by convertGps.pde 
into the data file for this sketch. Visualises elevations (heights) on my journey to Goldsmiths. 

Ignore the x data in this version which was adapted from my earlier program
 Dare 2012 */

float[] as, lon, lat;
float x, y;
int index;
ArrayList thatXPos = new ArrayList(); //array for X
ArrayList thatYPos = new ArrayList(); //array for Y
//y in this case is elevation data
float lonMax, lonMin, latMax, latMin; //to be our min and max values

void setup() {
  // noLoop();
  size(250, 220);
  as = float(loadStrings("cleanfile.txt")); /*create this file in 'convertGPS.pde */
  background(0);
}


void draw() {
  // background(255);
  println(mouseX);
  ///you might have to adjust start and ends but this seems to work
  for (int i =0;i<as.length-2;i+=2) { //all the longitude every 3rd
    thatXPos.add(as[i]);
  }

  ///you might have to adjust start and ends but this seems to work
  for (int i =1;i<as.length-1;i+=2) { //all the  Y latitude
    thatYPos.add(as[i]);
  }


  int len = thatXPos.size();
  int len2 = thatYPos.size();
  Float[] fa = new Float[len];
  Float[] fa2 = new Float[len2];
  float[] xPosCount = new float[len];
  float[] yPosCount = new float[len2];
  thatXPos.toArray(fa);
  thatYPos.toArray(fa2);


  for (int i =0;i< len; i++) {

    xPosCount[i] = fa[i];
  }

  for (int i =0;i< len2; i++) {

    yPosCount[i] = fa2[i];
  }



  lonMax =max(xPosCount);
  lonMin =min(xPosCount);




  latMax =max(yPosCount);
  latMin =min(yPosCount);

  /*  fill(255);
   text(lonMax, 10, 30);
   text(lonMin, 10, 50);
   text(latMax, 180, 30);
   text(latMin, 180, 50);
   */


  // for (int i = 0; i < len; i++) {
  if (index < len) {
    x =xPosCount[index];
    y =yPosCount[index];
    //println("lat:  "+xPosCount[i] + "lon: "+yPosCount[i]*-1);

    //use the minimums and maximums to calculate map()
    float x1= map(x, lonMin, lonMax, 50, width-50);
    float y2= map(y, latMin, latMax, 50, height-50);

    fill(255, 0, 0, 240);

    stroke(255, 0, 0);
    line(index*5, height, index*5, height-y2);

    // point( x1, y2);
    // println("lat:  "+x1 + "lon: "+y2);
  }

  index = index +1;
}


void mousePressed() {

  save("elevation.gif");
}
//end

Sunday, 15 July 2012

Unsatisfactory but functioning Android synthesis hack

 An unsatisfactory Android synthesis hack I tested this morning, I know there is a less deprecated way of doing this, but for now I'm happy that I've got a sine tone working through Android for Processing in Eclispe:

//the tone is generated when you press the screen, it works on my utterly rubbish Arnova 10b G3, //which, despite umpteen resets, has crazed dysfunctional calibration on the touch screen - a total lemon.


package processing.test.ansynth;

import processing.core.*; 

import android.view.MotionEvent
import android.view.KeyEvent
import android.app.Activity;
import android.graphics.Bitmap
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;

import java.io.*; 
import java.util.*; 

public class AnSynth extends PApplet {

public float sf;
    // originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html
    // and modified by Steve Pomeroy <steve@staticfree.info>
    private final int duration = 3; // seconds
    private final int sampleRate = 8000;
    private final int numSamples = duration * sampleRate;
    private final double sample[] = new double[numSamples];
    private final double freqOfTone = 440; // hz

    private final byte generatedSnd[] = new byte[2 * numSamples];

   // Handler handler = new Handler();

   public void setup(){   genTone();   playSound();
   
   }
   
public void draw(){
background(0, 0, 255);
fill(255, 0, 0);
     ellipse(width/2, height/2,80, 80);
     if(mousePressed){
     
     genTone();   
     playSound();
     
     }
}



   

    Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  //     setContentView(R.layout.main);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Use a new tread as this can take a while
        final Thread thread = new Thread(new Runnable() {
            public void run() {
            //    genTone();
                handler.post(new Runnable() {

                    public void run() {
                    //  genTone();
                    }
                });
            }
        });
        thread.start();
    }

    void genTone(){
        // fill out the array
        for (int i = 0; i < numSamples; ++i) {
            sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
       
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        int idx = 0;
        for (final double dVal : sample) {
            // scale to maximum amplitude
            final short val = (short) ((dVal * 32767));
            // in 16 bit wav PCM, first byte is the low order byte
            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
       

            sf = (float)(val & 0x00ff);
        }
    }

    void playSound(){
        @SuppressWarnings("deprecation") //crap I know
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, numSamples,
                AudioTrack.MODE_STATIC);
        audioTrack.write(generatedSnd, 0, generatedSnd.length);
        audioTrack.play();
    }
}
  

Wednesday, 11 July 2012

get the raw gps data into new lines

Fisrt thing that is useful to do for my other two programs is get the data onto separate lines, then use the txt file in the converter program below that, yep, its a long process



//put the data we want on new lines save then convert with convertGPS.pde
String[] lines, array4;




void setup() {
  lines = loadStrings("test4.gpx");
  String str1 = join(lines, " "); //make into a string so we can split


  String[] array1 = split(str1, '>'); //remove '>'


  String str2 = join(array1, ""); //make into a string again
  String[] array2 = split(str2, '='); //remove = signs
  String str3 = join(array2, "\n");
  String[] array3 = split(str3, '>');
  String str4 = join(array3, '\n');
  array4= split(str4, '<');
  for (int i = 0; i < array4.length; i++) {


    println(array4[i]);
  }
}




void draw() {
}


void keyPressed() { // Press a key to save the data




  saveStrings("lines.txt", array4);
  exit(); // Stop the program
}




///Finally remove all empty new lines: found this on the Processing site, works perfectly:



String lines[];
String[] neww = new String[1];




void setup() {


  lines = loadStrings("gps.txt");
  for (int i = 0; i < lines.length; i++) 
  {
    if (!lines[i].equals("")) {
      neww = append(neww, lines[i]);
    }
  }
}




void draw() {
}


void keyPressed() {
  saveStrings("cleanfile.txt", neww); 
  exit();
}



Paper accepted for Live Interfaces conference at Leeds

Shabina and I have had our Paper accepted for Live Interfaces conference at Leeds,: Skype, code and shouting! :-)

Pre-process GPS data in Processing





For the last couple of days I've been wrestling with making GPS data from phones etc into a useable form, using data such as :




<trkpt lat="51.5171129"
lon="-0.1776164">
<ele>30.999</ele>
<trkpt lat="31.5171129"
 lon="-0.6776164">
<ele>30.999</ele>
<trkpt lat="59.5171129"
lon="-0.5776164">
<ele>30.999</ele>
<trkpt lat="54.5171129"
lon="-0.5476164">
<ele>30.949</ele>
<time>2012-05-20T12:49:11.961Z</time>


which may not be on new lines, as above, but needs to be. The first useful program I've written uses regex (regular expressions) to get rid of the unwanted stuff and just grab the decimal values, which are printed to a file called gps.txt, which will be used in the program below this to map nicely to a Processing window.




/*
Read in raw GPS and print it as just decimal numbers
 Press any key to save it
 Dare July 2012


 */


PrintWriter output;
String[] lines;
String[] lines2;
String[] gps1;
int index = 0;
String strippedString, whole;
void setup() {
  size(200, 500);
  background(0);
  stroke(255);
  frameRate(12);
  output = createWriter("gps.txt");
  lines = loadStrings("data.txt");
}




void draw() {
  noLoop();
  smooth();
  background(0);
  if (index < lines.length) {
    String[] pieces = split(lines[index], "\n");
    String[] lines2 = new String[lines.length];
    for (int i =0;i<lines.length;i++) {
      lines2[i] =lines[i];
      println(getNumber(lines2[i]));
      String[] gps = new String[lines2.length];
      gps[i]=lines2[i];
      text(getNumber(lines2[i]), 20, 20+i*20);
      output.println(getNumber(lines2[i]) + "");
    }
  }
}






//use regex to get the decimal numbers:
String getNumber(String str) {
  Pattern pattern = Pattern.compile("\\b(\\d+)\\.(\\d+)\\b");


  Matcher matcher = pattern.matcher(str);
  String number = "";
  while (matcher.find ()) {


    number =matcher.group();
  }
  return number;
}




void keyPressed() { // Press a key to save the data


  output.flush(); // Write the remaining data
  output.close(); // Finish the file
  exit(); // Stop the program
}
//end

The second program then gets the longitude and latitude values only (though it could get the elevations as well) finds their minimum and maximum values and then maps them to the window size:


/*get the gps data (once it has been re-formatted in our other program 'convertGPS')
 get the mins and max values ofr longitude and latitude and map to new values
 */

float[] as, lon, lat;
float x, y;
ArrayList thatXPos = new ArrayList(); //array for X lat
ArrayList thatYPos = new ArrayList(); //array for Y long

float lonMax, lonMin, latMax, latMin; //to be our min and max values

void setup() {
  size(600, 400);
  as = float(loadStrings("gps.txt")); /*create thsi file in 'convertGPS.pde */
  background(0);
}


void draw() {
  // background(255);

  ///you might have to adjust start and ends but this seems to work
  for (int i =0;i<as.length-3;i+=3) { //all the latitude every 3rd
    thatXPos.add(as[i]);
  }

  ///you might have to adjust start and ends but this seems to work
  for (int i =1;i<as.length-2;i+=3) { //all the  Y longitude
    thatYPos.add(as[i]);
  }


  int len = thatXPos.size();
  int len2 = thatYPos.size();
  Float[] fa = new Float[len];
  Float[] fa2 = new Float[len2];
  float[] xPosCount = new float[len];
  float[] yPosCount = new float[len2];
  thatXPos.toArray(fa);
  thatYPos.toArray(fa2);


  for (int i =0;i< len; i++) {

    xPosCount[i] = fa[i];
  } 

  for (int i =0;i< len2; i++) {

    yPosCount[i] = fa2[i];
  } 


//apologies for stupid naming! :-S
  lonMax =max(xPosCount); //names are stupid, got head in a twist with lat and long
  lonMin =min(xPosCount); //actually latitude, but doesn't matter as is a name only
  latMax =max(yPosCount); //actually longitude
  latMin =min(yPosCount);


  for (int i = 0; i < len; i++) {

    x =xPosCount[i];
    y =yPosCount[i];

    //use the minimums and maximums to calculate map()
    float x1= map(x, lonMin, lonMax, 40, width-50);
    float y2= map(y, latMin, latMax, 40, height-50);

    fill(255, 0, 0);
    ellipse(x1, y2, 10, 10);
    //print(" *"+x1 + " "+y2);
  }
}
////end