Problem adding a millisecond delay between iterations within a for loop (a Twitter4j search)
in
Contributed Library Questions
•
2 years ago
Hi there, I've had some problems with a project over the past few days that collects and displays tweets to a 3D Earth using Twitter4j. I'm quite a new programmer so I'm learning as I go and this forum has become a great resource.
Essentially I have a string that is updated to be the latest tweet that is stored within a hashmap. The hashmap is updated when I run a search using Twitter4J for a particular keyword and the string is then displayed to the screen. This gives me a brief look at various tweets that are being stored in the hashmap but ultimately it displays the last one stored after about 3 seconds which is all much too fast for my user experience. So I was wondering if there was a way to slow down the Twitter4J query so that the string displays the located tweet for say 5 seconds before querying again and changing the content of the string that is displayed? I've tried adjusting the thread's wait integer but to no avail.
Here is my program:
import processing.core.*;
import processing.xml.*;
//import javax.media.opengl.*;
//import processing.opengl.*;
import controlP5.*;
import peasy.org.apache.commons.math.*;
import peasy.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import twitter4j.http.*;
import twitter4j.api.*;
import twitter4j.util.*;
import twitter4j.internal.http.*;
import twitter4j.*;
import toxi.geom.*;
import toxi.processing.*;
import peasy.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
import twitter4j.internal.util.*;
import twitter4j.api.*;
import toxi.geom.mesh.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.util.*;
import peasy.org.apache.commons.math.*;
import twitter4j.*;
import toxi.geom.mesh2d.*;
import peasy.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import toxi.util.datatypes.*;
import toxi.math.waves.*;
import toxi.geom.mesh.subdiv.*;
import toxi.geom.*;
import toxi.util.events.*;
import processing.xml.*;
import processing.core.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import peasy.test.*;
import toxi.math.conversion.*;
import twitter4j.internal.http.*;
import toxi.math.noise.*;
import toxi.processing.*;
import toxi.util.*;
import twitter4j.http.*;
import controlP5.*;
//import processing.opengl.*;
import toxi.math.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
public class CityCTRLa extends PApplet {
boolean a = true;
boolean button = false;
boolean buttona = false;
int x = 750;
int y = 106;
int w = 20;
int h = 20;
int xa = 750;
int ya = 50;
int wa = 20;
int ha = 20;
PImage bg, texmap;
PFont font;
int sDetail = 55; //Sphere detail
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[], cosLUT[], sincos_precision = 0.5f;
int sincos_length = PApplet.parseInt(360.0f / sincos_precision);
float r = 600;
// r = earth radius in px. 6371 is earth radius in km.
float pxToKm = 6371.0f / r;
int inRange;
String searchString;
String searchState = "";
String consumerKey = "5cO4mwCxSzh2IDixU6rKEg";
String consumerSecret = "vL3YbYclatCdFNcDzBds8BMX87mCxSqSdn0YFh8XA";
String accessToken = "319951547-kPyfRlb9MHt2LwjEtIsR2uaqAvH49dQvj5nR4gyQ";
String accessTokenSecret = "V7juyEfTgWGbeMAaVJRbiZdwJB3bCDHHPmClKN5l0";
PeasyCam cam;
PeasyDragHandler PanDragHandler;
PFont imhelix;
ControlP5 controlP5;
PMatrix3D currCameraMatrix;
//final String SEARCH_QUERY="hello";
final int TIME_STEP = 1;
final int NUM_SEARCHES = 25;
final long DAY_DURATION = 1000*60*60*24;
Twitter twitter = new TwitterFactory().getInstance();
HashMap<Long,Tweet> tweets=new HashMap<Long,Tweet>();
Iterator i = tweets.entrySet().iterator(); // Get an iterator
ToxiclibsSupport gfx;
SimpleThread thread1;
public void setup(){
searchString = "";
imageMode(CENTER);
controlP5 = new ControlP5(this);
cam = new PeasyCam(this, 1500);
cam.setMinimumDistance(750);
cam.setMaximumDistance(2000);
cam.rotateZ(-HALF_PI);
cam.rotateZ(-HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateX(QUARTER_PI);
cam.setResetOnDoubleClick(false);
cam.setCenterDragHandler(null);
bezierDetail(30);
font = createFont("ArialNarrow", 20);
textFont(font);
twitter = new TwitterFactory().getOAuthAuthorizedInstance(consumerKey,consumerSecret, new AccessToken(accessToken,accessTokenSecret));
size(864,400,P3D);
//hint(DISABLE_OPENGL_ERROR_REPORT);
frameRate(30);
rectMode(CENTER);
texmap = loadImage("world32kb.jpg");
initializeSphere(sDetail);
gfx=new ToxiclibsSupport(this);
//searchTwitter(SEARCH_QUERY);
thread1 = new SimpleThread(1000,"a");
thread1.start();
controlP5 = new ControlP5(this);
}
public void hud(PeasyCam cam)
{
cam.beginHUD();
pushMatrix();
translate(100, height-120, 0);
fill(255, 200);
noStroke();
textSize(16);
fill(242,242,242);
float tw = textWidth(searchString);
fill(210,210,210);
noStroke();
// rect(-90,107,tw+10,20);
fill (175);
rect (x, y, w, h);
fill(242,242,242);
text(searchString, -90, 107);
textSize(16);
text(tweets.toString(), 28, -168,240,200);
stroke(242,242,242);
if(second()%2 == 0)
line(tw+-82, 107, tw+-87, 107);
if(searchState.equals("nomatches")){
stroke(0);
noFill();
rect(1,30, 65, 30);
fill(0, 200);
text("No matches!", 8, 50);
}
if(searchState.equals("fail")){
stroke(0);
noFill();
rect(1,30, 170, 30);
fill(0, 200);
text("Parameterless search is not allowed!", 8, 50);
}
popMatrix();
cam.endHUD();
}
public void searchTwitter(String searchQuery) {
twitter4j.Query query = new twitter4j.Query(searchQuery);
//twitter4j.Query.setGeoCode(new GeoLocation(52.30, 13.25), 1000.0, twitter4j.Query.KILOMETERS); // if we want to only get tweets from the region berlin
query.rpp(100);
Date referenceDate=new Date();
for(int i=0; i<NUM_SEARCHES; i++) {
String d=new SimpleDateFormat("yyyy-MM-dd").format(referenceDate);
//println("executing search for date: "+d);
query.until(d);
// execute search
try {
QueryResult result = twitter.search(query);
for (Tweet tweet : result.getTweets()) {
// first check if ID is unique?
if (tweets.get(tweet.getId())==null) {
// filter out tweets with GPS loc
GeoLocation loc=tweet.getGeoLocation();
if (loc!=null) {
tweets.put(tweet.getId(),tweet);
//println("adding tweet: "+tweet);
}
} else {
//println("skipping: "+tweet.getId());
}
}
}
catch(TwitterException e) {
println(e.getMessage());
}
referenceDate.setTime(referenceDate.getTime()-TIME_STEP*DAY_DURATION);
}
}
public void draw() {
directionalLight(255, 255, 255, 0, -1, 0);
//lights();
ambientLight(255, 255, 255);
translate(80, 50, 0);
float fov = PI/3.0f;
float cameraZ = (height/2.0f) / tan(fov/2.0f);
perspective(fov, PApplet.parseFloat(width)/PApplet.parseFloat(height),
cameraZ/40.0f, cameraZ*40.0f);
inRange = 0;
background(25,25,25);
renderGlobe();
stroke(255);
//gfx.origin(300);
//searchTwitter(SEARCH_QUERY);
int a = thread1.getCount();
text(a,10,50);
// iterate over all collected tweets
for(Tweet tweet : tweets.values()) {
GeoLocation loc=tweet.getGeoLocation();
// convert geo location into cartesian world coordinates
Vec3D p=new Vec3D(600,radians((float)loc.getLongitude())-HALF_PI,radians((float)loc.getLatitude())).toCartesian();
// create a box at the computed position
AABB box=new AABB(p,2);
noStroke();
fill(255,120,0);
// draw box at position
gfx.box(box);
// text(tweets,15,15);
fill(255);
controlP5.draw(); }
hud(cam);
}
class SimpleThread extends Thread {
boolean running; // Is the thread running? Yes or no?
int wait; // How many milliseconds should we wait in between executions?
String id; // Thread name
int count; // counter
boolean doSearch = false; // search trigger
public boolean getRunning(){
return running;
}
// Constructor, create the thread
// It is not running by default
SimpleThread (int w, String s) {
wait = w;
running = false;
id = s;
count = 0;
}
public void start () {
// Set running equal to true
running = true;
// Print messages
println("Starting thread (will execute every " + wait + " milliseconds.)");
// Do whatever start does in Thread, don't forget this!
super.start();
}
// We must implement run, this gets triggered by start()
public void run () {
while (running) {
if (doSearch) {
searchTwitter(searchString);
println("Search for " + searchString + " done");
doSearch = false;
}
// println(id + ": " + count);
count++;
// Ok, let's wait for however long we should wait
// try {
// sleep((long)(wait));
// } catch (Exception e) {
// }
}
System.out.println(id + ": thread is done!"); // The thread is done when we get to the end of run()
}
public void search() {
doSearch = true;
}
public int getCount() {
return count;
}
public void quit() {
System.out.println("Quitting.");
running = false; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
}
public void keyPressed() {
if(((key>='A')&&(key<='Z')) || ((key>='a')&&(key<='z')) || ((key>='0')&&(key<='9')) || (key==' ')){
searchString += key;
}
// if(key == DELETE && thread1.getRunning()){
// println(searchString);
// thread1.quit();
//
// }
else if(key == ENTER){thread1.search();
searching = true;
}
if(key == BACKSPACE){
if(searchString.length()>0)
searchString = searchString.substring(0,searchString.length()-1);
}
}
public void renderGlobe()
{
pushMatrix();
translate(0,0,0);
fill(255);
stroke(0);
//sphere(r);
noFill();
pushMatrix();
rotateY(radians(-90));
rotateZ(radians(180));
noStroke();
textureMode(IMAGE);
texturedSphere(r, texmap);
popMatrix();
popMatrix();
}
// Converts 3D cartesian coordinates to polar coordinates
//
// theVector : vector to convert
// returns : vector containing 'length', 'angleY' and 'angleZ',
// so that rotating a point (length, 0, 0) first
// around the y-axis with angleY and then around the
// z-axis with angleZ results again in point (x, y, z)
public PVector cartesianToPolar(PVector theVector) {
PVector res = new PVector();
res.x = theVector.mag();
if (res.x > 0) {
res.y = -atan2(theVector.z, theVector.x);
res.z = asin(theVector.y / res.x);
}
else {
res.y = 0;
res.z = 0;
}
return res;
}
class Satellite {
float lat, lng, x, y, z, elevation;
String[] positions;
int id;
Satellite(int id, float _lat, float _lng, float _elevation) {
this.id = id;
elevation = _elevation;
lat = radians(_lat);
lng = radians(90f-_lng);
positions = new String[0];
}
public void display() {
lat += .001f;
//lng += .008;
pushMatrix();
translate(x, y, z);
fill(255);
stroke(0);
box(20);
float[] rotations = cam.getRotations();
rotateX(rotations[0]);
rotateY(rotations[1]);
rotateZ(rotations[2]);
text("Satellite #" + id + "\n" + lat + "\n" + lng, 20, 0);
fill(255);
popMatrix();
}
}
class locationOnGlobe {
float lat, lng, x, y, z;
locationOnGlobe(float _lat, float _lng) {
lat = radians(_lat);
lng = radians(90f-_lng);
}
public void display() {
lng += random(0.001f, 0.0005f);
pushMatrix();
translate(x, y, z);
fill(255, 0, 0);
noStroke();
sphere(10);
popMatrix();
update();
}
public void update() {
x = r*cos(lat)*cos(lng);
y = r*cos(lat)*sin(lng);
z = r*sin(lat);
}
}
public void initializeSphere(int res)
{
sinLUT = new float[sincos_length];
cosLUT = new float[sincos_length];
for (int i = 0; i < sincos_length; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * sincos_precision);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * sincos_precision);
}
float delta = (float)sincos_length/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % sincos_length];
cz[i] = sinLUT[(int) (i*delta) % sincos_length];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (sincos_length*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % sincos_length];
float currY = -cosLUT[(int) angle % sincos_length];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
public void texturedSphere(float r, PImage t)
{
int v1,v11,v2;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
//vertex(0, r, 0,u, v+iv);
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#c0c0c0", "CityCTRLa" });
}
}
Many thanks for your assistance.
Essentially I have a string that is updated to be the latest tweet that is stored within a hashmap. The hashmap is updated when I run a search using Twitter4J for a particular keyword and the string is then displayed to the screen. This gives me a brief look at various tweets that are being stored in the hashmap but ultimately it displays the last one stored after about 3 seconds which is all much too fast for my user experience. So I was wondering if there was a way to slow down the Twitter4J query so that the string displays the located tweet for say 5 seconds before querying again and changing the content of the string that is displayed? I've tried adjusting the thread's wait integer but to no avail.
Here is my program:
import processing.core.*;
import processing.xml.*;
//import javax.media.opengl.*;
//import processing.opengl.*;
import controlP5.*;
import peasy.org.apache.commons.math.*;
import peasy.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import twitter4j.http.*;
import twitter4j.api.*;
import twitter4j.util.*;
import twitter4j.internal.http.*;
import twitter4j.*;
import toxi.geom.*;
import toxi.processing.*;
import peasy.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
import twitter4j.internal.util.*;
import twitter4j.api.*;
import toxi.geom.mesh.*;
import peasy.org.apache.commons.math.geometry.*;
import twitter4j.util.*;
import peasy.org.apache.commons.math.*;
import twitter4j.*;
import toxi.geom.mesh2d.*;
import peasy.*;
import twitter4j.internal.org.json.*;
import twitter4j.internal.logging.*;
import toxi.util.datatypes.*;
import toxi.math.waves.*;
import toxi.geom.mesh.subdiv.*;
import toxi.geom.*;
import toxi.util.events.*;
import processing.xml.*;
import processing.core.*;
import twitter4j.conf.*;
import twitter4j.internal.async.*;
import peasy.test.*;
import toxi.math.conversion.*;
import twitter4j.internal.http.*;
import toxi.math.noise.*;
import toxi.processing.*;
import toxi.util.*;
import twitter4j.http.*;
import controlP5.*;
//import processing.opengl.*;
import toxi.math.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
public class CityCTRLa extends PApplet {
boolean a = true;
boolean button = false;
boolean buttona = false;
int x = 750;
int y = 106;
int w = 20;
int h = 20;
int xa = 750;
int ya = 50;
int wa = 20;
int ha = 20;
PImage bg, texmap;
PFont font;
int sDetail = 55; //Sphere detail
float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[], cosLUT[], sincos_precision = 0.5f;
int sincos_length = PApplet.parseInt(360.0f / sincos_precision);
float r = 600;
// r = earth radius in px. 6371 is earth radius in km.
float pxToKm = 6371.0f / r;
int inRange;
String searchString;
String searchState = "";
String consumerKey = "5cO4mwCxSzh2IDixU6rKEg";
String consumerSecret = "vL3YbYclatCdFNcDzBds8BMX87mCxSqSdn0YFh8XA";
String accessToken = "319951547-kPyfRlb9MHt2LwjEtIsR2uaqAvH49dQvj5nR4gyQ";
String accessTokenSecret = "V7juyEfTgWGbeMAaVJRbiZdwJB3bCDHHPmClKN5l0";
PeasyCam cam;
PeasyDragHandler PanDragHandler;
PFont imhelix;
ControlP5 controlP5;
PMatrix3D currCameraMatrix;
//final String SEARCH_QUERY="hello";
final int TIME_STEP = 1;
final int NUM_SEARCHES = 25;
final long DAY_DURATION = 1000*60*60*24;
Twitter twitter = new TwitterFactory().getInstance();
HashMap<Long,Tweet> tweets=new HashMap<Long,Tweet>();
Iterator i = tweets.entrySet().iterator(); // Get an iterator
ToxiclibsSupport gfx;
SimpleThread thread1;
public void setup(){
searchString = "";
imageMode(CENTER);
controlP5 = new ControlP5(this);
cam = new PeasyCam(this, 1500);
cam.setMinimumDistance(750);
cam.setMaximumDistance(2000);
cam.rotateZ(-HALF_PI);
cam.rotateZ(-HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateY(HALF_PI);
cam.rotateX(QUARTER_PI);
cam.setResetOnDoubleClick(false);
cam.setCenterDragHandler(null);
bezierDetail(30);
font = createFont("ArialNarrow", 20);
textFont(font);
twitter = new TwitterFactory().getOAuthAuthorizedInstance(consumerKey,consumerSecret, new AccessToken(accessToken,accessTokenSecret));
size(864,400,P3D);
//hint(DISABLE_OPENGL_ERROR_REPORT);
frameRate(30);
rectMode(CENTER);
texmap = loadImage("world32kb.jpg");
initializeSphere(sDetail);
gfx=new ToxiclibsSupport(this);
//searchTwitter(SEARCH_QUERY);
thread1 = new SimpleThread(1000,"a");
thread1.start();
controlP5 = new ControlP5(this);
}
public void hud(PeasyCam cam)
{
cam.beginHUD();
pushMatrix();
translate(100, height-120, 0);
fill(255, 200);
noStroke();
textSize(16);
fill(242,242,242);
float tw = textWidth(searchString);
fill(210,210,210);
noStroke();
// rect(-90,107,tw+10,20);
fill (175);
rect (x, y, w, h);
fill(242,242,242);
text(searchString, -90, 107);
textSize(16);
text(tweets.toString(), 28, -168,240,200);
stroke(242,242,242);
if(second()%2 == 0)
line(tw+-82, 107, tw+-87, 107);
if(searchState.equals("nomatches")){
stroke(0);
noFill();
rect(1,30, 65, 30);
fill(0, 200);
text("No matches!", 8, 50);
}
if(searchState.equals("fail")){
stroke(0);
noFill();
rect(1,30, 170, 30);
fill(0, 200);
text("Parameterless search is not allowed!", 8, 50);
}
popMatrix();
cam.endHUD();
}
public void searchTwitter(String searchQuery) {
twitter4j.Query query = new twitter4j.Query(searchQuery);
//twitter4j.Query.setGeoCode(new GeoLocation(52.30, 13.25), 1000.0, twitter4j.Query.KILOMETERS); // if we want to only get tweets from the region berlin
query.rpp(100);
Date referenceDate=new Date();
for(int i=0; i<NUM_SEARCHES; i++) {
String d=new SimpleDateFormat("yyyy-MM-dd").format(referenceDate);
//println("executing search for date: "+d);
query.until(d);
// execute search
try {
QueryResult result = twitter.search(query);
for (Tweet tweet : result.getTweets()) {
// first check if ID is unique?
if (tweets.get(tweet.getId())==null) {
// filter out tweets with GPS loc
GeoLocation loc=tweet.getGeoLocation();
if (loc!=null) {
tweets.put(tweet.getId(),tweet);
//println("adding tweet: "+tweet);
}
} else {
//println("skipping: "+tweet.getId());
}
}
}
catch(TwitterException e) {
println(e.getMessage());
}
referenceDate.setTime(referenceDate.getTime()-TIME_STEP*DAY_DURATION);
}
}
public void draw() {
directionalLight(255, 255, 255, 0, -1, 0);
//lights();
ambientLight(255, 255, 255);
translate(80, 50, 0);
float fov = PI/3.0f;
float cameraZ = (height/2.0f) / tan(fov/2.0f);
perspective(fov, PApplet.parseFloat(width)/PApplet.parseFloat(height),
cameraZ/40.0f, cameraZ*40.0f);
inRange = 0;
background(25,25,25);
renderGlobe();
stroke(255);
//gfx.origin(300);
//searchTwitter(SEARCH_QUERY);
int a = thread1.getCount();
text(a,10,50);
// iterate over all collected tweets
for(Tweet tweet : tweets.values()) {
GeoLocation loc=tweet.getGeoLocation();
// convert geo location into cartesian world coordinates
Vec3D p=new Vec3D(600,radians((float)loc.getLongitude())-HALF_PI,radians((float)loc.getLatitude())).toCartesian();
// create a box at the computed position
AABB box=new AABB(p,2);
noStroke();
fill(255,120,0);
// draw box at position
gfx.box(box);
// text(tweets,15,15);
fill(255);
controlP5.draw(); }
hud(cam);
}
class SimpleThread extends Thread {
boolean running; // Is the thread running? Yes or no?
int wait; // How many milliseconds should we wait in between executions?
String id; // Thread name
int count; // counter
boolean doSearch = false; // search trigger
public boolean getRunning(){
return running;
}
// Constructor, create the thread
// It is not running by default
SimpleThread (int w, String s) {
wait = w;
running = false;
id = s;
count = 0;
}
public void start () {
// Set running equal to true
running = true;
// Print messages
println("Starting thread (will execute every " + wait + " milliseconds.)");
// Do whatever start does in Thread, don't forget this!
super.start();
}
// We must implement run, this gets triggered by start()
public void run () {
while (running) {
if (doSearch) {
searchTwitter(searchString);
println("Search for " + searchString + " done");
doSearch = false;
}
// println(id + ": " + count);
count++;
// Ok, let's wait for however long we should wait
// try {
// sleep((long)(wait));
// } catch (Exception e) {
// }
}
System.out.println(id + ": thread is done!"); // The thread is done when we get to the end of run()
}
public void search() {
doSearch = true;
}
public int getCount() {
return count;
}
public void quit() {
System.out.println("Quitting.");
running = false; // Setting running to false ends the loop in run()
// IUn case the thread is waiting. . .
interrupt();
}
}
public void keyPressed() {
if(((key>='A')&&(key<='Z')) || ((key>='a')&&(key<='z')) || ((key>='0')&&(key<='9')) || (key==' ')){
searchString += key;
}
// if(key == DELETE && thread1.getRunning()){
// println(searchString);
// thread1.quit();
//
// }
else if(key == ENTER){thread1.search();
searching = true;
}
if(key == BACKSPACE){
if(searchString.length()>0)
searchString = searchString.substring(0,searchString.length()-1);
}
}
public void renderGlobe()
{
pushMatrix();
translate(0,0,0);
fill(255);
stroke(0);
//sphere(r);
noFill();
pushMatrix();
rotateY(radians(-90));
rotateZ(radians(180));
noStroke();
textureMode(IMAGE);
texturedSphere(r, texmap);
popMatrix();
popMatrix();
}
// Converts 3D cartesian coordinates to polar coordinates
//
// theVector : vector to convert
// returns : vector containing 'length', 'angleY' and 'angleZ',
// so that rotating a point (length, 0, 0) first
// around the y-axis with angleY and then around the
// z-axis with angleZ results again in point (x, y, z)
public PVector cartesianToPolar(PVector theVector) {
PVector res = new PVector();
res.x = theVector.mag();
if (res.x > 0) {
res.y = -atan2(theVector.z, theVector.x);
res.z = asin(theVector.y / res.x);
}
else {
res.y = 0;
res.z = 0;
}
return res;
}
class Satellite {
float lat, lng, x, y, z, elevation;
String[] positions;
int id;
Satellite(int id, float _lat, float _lng, float _elevation) {
this.id = id;
elevation = _elevation;
lat = radians(_lat);
lng = radians(90f-_lng);
positions = new String[0];
}
public void display() {
lat += .001f;
//lng += .008;
pushMatrix();
translate(x, y, z);
fill(255);
stroke(0);
box(20);
float[] rotations = cam.getRotations();
rotateX(rotations[0]);
rotateY(rotations[1]);
rotateZ(rotations[2]);
text("Satellite #" + id + "\n" + lat + "\n" + lng, 20, 0);
fill(255);
popMatrix();
}
}
class locationOnGlobe {
float lat, lng, x, y, z;
locationOnGlobe(float _lat, float _lng) {
lat = radians(_lat);
lng = radians(90f-_lng);
}
public void display() {
lng += random(0.001f, 0.0005f);
pushMatrix();
translate(x, y, z);
fill(255, 0, 0);
noStroke();
sphere(10);
popMatrix();
update();
}
public void update() {
x = r*cos(lat)*cos(lng);
y = r*cos(lat)*sin(lng);
z = r*sin(lat);
}
}
public void initializeSphere(int res)
{
sinLUT = new float[sincos_length];
cosLUT = new float[sincos_length];
for (int i = 0; i < sincos_length; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * sincos_precision);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * sincos_precision);
}
float delta = (float)sincos_length/res;
float[] cx = new float[res];
float[] cz = new float[res];
// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % sincos_length];
cz[i] = sinLUT[(int) (i*delta) % sincos_length];
}
// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;
// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (sincos_length*0.5f)/res;
float angle = angle_step;
// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % sincos_length];
float currY = -cosLUT[(int) angle % sincos_length];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}
public void texturedSphere(float r, PImage t)
{
int v1,v11,v2;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();
// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}
// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;
// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
//vertex(0, r, 0,u, v+iv);
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();
}
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#c0c0c0", "CityCTRLa" });
}
}
Many thanks for your assistance.
1