Datascapes FAQ

The point of this page is to be a group FAQ. You should feel free to post a question AND post responses, edit mistakes, etc.

In order to make this work well, you must understand two things about wikispaces:
1. How to make an "anchor", which is a point in this webpage to which you can link precisely so that we can have a correct table of contents.
2. How to put your code in a good format. This is explained here, or you can just see how I did it below when you "edit this page".



Contents:

1. How do I insert an alpha channel in my saved images from processing?

2. Is it possible to clear a specific element during each draw loop (and leave the rest displayed)?
(2A: I would like to be able to display a trail of dots. In the below code, I am resetting the background to black in every draw loop. This clears the screen completely. Is there a way to clear only the line, leaving the dots?)

3. I downloaded the latest version of worldwind and created the necessary folders within the processing directory. I then pasted in the ten lines of code and well received a number of errors. Not sure how to get it to work. Anyone have any success with it?
The code I pasted in to activate worldwind...

import gov.nasa.worldwind.*;
import gov.nasa.worldwind.awt.*;
 
void setup()
{
size(500, 500, JAVA2D);
 
WorldWindowGLCanvas wwd = new WorldWindowGLCanvas();
wwd.setSize(width, height);
this.add(wwd);
 
Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
m.setShowWireframeExterior(true);
m.setShowWireframeInterior(false);
m.setShowTessellationBoundingVolumes(false);
wwd.setModel(m);
}
The error text looks something like this:
C:/DOCUME~1/Arthur/LOCALS~1/Temp/build27930.tmp/Temporary_9645_3532.java:12:58:12:62: Semantic Error: No accessible field named "AVKey" was found in type "Temporary_9645_3532".

4. How do I post an applet to the wiki?






Answers:


1. How do I insert an alpha channel in my saved images from processing?

Answer 1: use Photoshop! But this is obviously not very "real-time" unless you script Photoshop, which I don't happen to know how to do off-hand.
Answer 2: Give your Processing pixels an alpha channel before you save your image.
Every pixel in processing is stored as a "color" type. The color type in processing can be expressed in several different ways, the most standard of which is just "RGB" (three integers for red,green,blue). In order to get the alpha channel in there, you need to insert a fourth color value, which is the alpha channel. See the code below, which just passes through the current image on the screen and sets every black pixel (i.e. pixels with a color of (0,0,0)) to have an alpha channel of zero (i.e. now it's a color(0,0,0,0)).

/* NOTE: the "mousePressed" function may not be the best place for you to run this code. You should
run it wherever is appropriate -- right before you try to save the image file. */
void mousePressed()
{
 color black = color(0,0,0); // are your "background" pixels black? Or do you need to change this?
 PImage b = get();
 b.format = ARGB;
 loadPixels();
 
 // This loop just goes through all the pixels in the image, giving any black pixel
 // an alpha value of zero -- i.e. making it transparent.
 for (int i = 0; i < width*height; i = i+1) {
 if (b.pixels[i] == black) {
 color a = color(0,0,0,0); // the fourth zero is the new alpha channel
 b.pixels[i] = a;
 }
 }
 updatePixels();
 
 // You should change this to wherever you want your file to go! (i.e. wherever // Google Earth is looking for it)
 b.save("C:/george/teaching/mediaSCAPES/code_and_tools/test_output/circles-1.png");
}


Answer 3: See the below for a code that checks an image brightness value and gives each pixel an alpha value bases on that value - i.e. the lighter it is the more transparent the pixel becomes...

size(516, 387);  //set your image size here
PImage c;  // Declare variable "c" of type PImage
c = loadImage("SpaceLaunch.jpg"); // Load the images into the program
c.format = ARGB;  // converts image to ARGB format
loadPixels(); //loads image pixels into an array "c.pixels"
 
 
//this part iterates through the pixel array, determining the brightness, and R,G,B values for each pixel.
//It then feeds the inverse of the brightness value back into the alpha channel of the pixel.
for(int i = 0; i < width*height; i = i+1) {
  float a = brightness(c.pixels[i]);
  a = 255 - a;
  //print(a);
  float r = red(c.pixels[i]);
  float g = green(c.pixels[i]);
  float b = blue(c.pixels[i]);
  color New = color(r,g,b,a);
  c.pixels[i] = New;
}
 
image(c, 0, 0); // Displays the image from point (0,0)





2. Is it possible to clear a specific element during each draw loop (and leave the rest displayed)?

Answer:
Almost certainly! What do you mean by an "element" in this case, however? Is it a pixel or some geometrically defined thing? Either way, it's a question of having the right data structure in which to store and keep track of your elements.

If you're actually talking about pixels, then Processing already stores those for you in an array. But you might find what you really need to know then is the set of indexes into that array (so, if you want to hide "pixel[134]", you obviously need to remember the number "134"!).

The most basic way to "remember" these things from one draw() loop to another is to use a global variable or two (or more). From one draw() call to another you can store values in these variables, because they 'survive' independently of functions (such as draw()) beginning or ending. Learn more about global vs. local variables in Processing here (or you can Google these terms and you'll get treatises on the subject, no doubt).

Of course you could have a global array of integers, which could store hundreds or thousands of indexes into your pixel array... Keeping two global arrays, "clicks_x[]" and "clicks_y[]" would be a good way to keep track of a sequence of mouse clicks, for instance.

Now, as for how to avoid drawing the particular 'element' you've remembered -- this just requires an "if(...)" statement that makes sure you don't call your drawing code on those elements you've decided to keep separate. This actually may be a little non-trivial for pixel-based calculations such as the Game of Life. You might need to let the Game of Life code run, then, before the pixels actually get displayed, go back through (loadPixels() again!) and 'black out' certain pixels. Or you could load an entire copy of the pixels[] array and store that each loop of the draw() function. This would double your overhead for the running of the program, but would let you do as you pleased with any pixel... like having an entire second deck of cards up your sleeve; you could show the 'official' result of the simulation, or your own version of that pixel.

Does this help? Otherwise please refine the question -- you could add some code.

(2A: I would like to be able to display a trail of dots. In the below code, I am resetting the background to black in every draw loop. This clears the screen completely. Is there a way to clear only the line, leaving the dots?)


Answer: Basically you are introducing an idea of 'history' into the drawing, where some elements will leave behind ghosts of themselves, and others won't. The most logical and general way to do this is probably to keep an array of these ghosts for each point. You can insert each point's current location into that array right before you move the point. Then, at the beginning of your draw() function, right after you clear the background, you loop through your history array(s) and re-draw those points.

One more layer of intelligence would be to let the history 'expire' over time, maybe by limiting the size of the array to 20 values (after which you need to remove the oldest value and add a new one to the end). You could also draw the different levels of history with varying alpha channel values, so they seem to fade in time... or expand, or even move...

To see an (albeit somewhat complicated) example of this, check out this particle code. This is object-oriented code, so his dots are objects called "Particles" (search the code for "Class Particle") and they have a bunch of functions associated with them. If you just search for his use of the "timer" variable, though, I think you'll see how he's using it to control the alpha channel, and also to decide (via the "dead()") function when to throw that particle away.

Also, to work your arrays correctly, you will probably want to know how to append() to the array, and also perhaps use subset(). You may find your code slowing down very rapidly, which is due to the very inefficient nature of the way arrays are manipulated. You could read about that here. Then, you might hit upon the friendly ArrayList class (which the particle code I referred to above uses). This is pure Java, but it works in Processing, and it does things like append() and remove() which will be very helpful.

This may all seem a bit complicated but once you understand how to dynamically manage a list of values (which is basically what we're talking about here) you are well on your way to manipulating data very richly!



4. How to post an applet
Basically an applet is just a .jar file sitting on the web server. If you can reference that file from your HTML code, you can run the applet. When you 'export' an applet from Processing, it creates all the html you need, but it does give the right file path for your .jar file -- well, it gives a 'local' path, which won't work when you're trying to get this thing to load on Wikispaces. So to get an applet to work on Wikispaces you just have to upload the .jar file, and then insert the right file path into your html and put that on the page. Here is a step-by-step guide...

a. In Processing, go to File->Export and give a file name and location for your applet. This will generate a new folder with several files in it.
b. Upload the .jar file from that new applet directory to the wikispaces site (like you would upload any file).
c. Open the .html file from that applet directory in a text editor (e.g. Notepad). You can't just double-click it, as this will 'browse' the file with your web browser. Once you have the .html file open, go through and find every reference to "yourappletname.jar" and replace it with "http://mediascapes.wikispaces.com/space/showimage/yourappletname.jar" . For example, this line:
<param name="archive" value="applet_test.jar" />
becomes
 <param name="archive" value="http://mediascapes.wikispaces.com/space/showimage/applet_test.jar" />

There are three lines where you need to do this.
d. If you want to be really cool, you should also insert that web path at the front of the reference to "yourappletname.pde" . If you do this you should also upload the .pde file from your applet directory to the wiki (as you did for the .jar file in "b", above). This will make your code available as a link, as in the example below.

e. Now, Edit the page on the wiki where you want to insert your applet. Click the little TV icon on the toolbar ("Insert Widget") and you will get a pop-up with a window asking you what kind of media you want to insert. Say "Other HTML" at the bottom and you will get the chance to type in HTML. Instead of typing anything, just copy and paste the entire .html file that you edited (as described in C and D above) into that little window. Now click Save to insert the applet. You should get a little grey widget saying "custom". Now save the wiki page and you should see your applet there running, as well as a link to your code.

f. Here's an example: you can edit this page and click on the "custom" widget below and then click the media icon (the TV icon on the toolbar) to actually see my HTML code.

This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.

Source code: applet_test

Built with Processing