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