FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Syntax
(Moderators: fry, REAS)
   ... over my head?
« Previous topic | Next topic »

Pages: 1 2 
   Author  Topic: ... over my head?  (Read 876 times)
Charles Hinshaw
Guest
Email
... over my head?
« on: Jan 27th, 2004, 12:13am »

I have started this in a new thread, since I think my last problem was solved, and that this is unrelated.
 
The objective is:
1. Open an image and make sure that it is gray scale.
2. Use the pixel values to determine the density of coordinates on the image (the darker a pixel, the more dense)
3. Place "particles" according to density.
4. Shuffle the particles about with 3D brownian motion.
 
1-3 all seem to be working (yeah, it is slow and the code needs to be optimized, which is currently beyond me) - I can produce an image made out of points from the particle objects BUT my program is falling all apart when it reaches the loop() where it tries to interact with the particles.
 
Please help me.
 
Thanks,
 
Charles Hinshaw
 
Code:

// User Control Variables
String imagename = "dust.jpg"; // Source Image
 
//Global Variables
particle p[];
int psum = 0;
 
// ---------------------------------------------------
void setup() // SET UP SOFTWARE
{
  // create the Processing environment
  size(200,200);
  framerate(30);
  smooth();
  background(255);
 
  // load an image from the user variable "imagename"
  BImage startimage;
  startimage = loadImage(imagename);
  image(startimage, 0, 0);
 
  // convert loaded image to greyscale and spit it upon the screen
  color c1 = get(0,0);
  color c2 = get(0,0);
  float bright = brightness(c1);
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 colorMode(HSB);
 c1 = get(x,y);
 bright = brightness(c1);
 colorMode(RGB);
 c2 = color(bright, bright, bright);
 set (x,y,c2);
    }
  }
 
  // create density array -  white = 0 and black = 255.
  int[][] density = new int[width][height];
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 int colors = get(x,y) & 0xff;
 colors = 100-int(colors/2.55);
 //c1 = 255-c1;
 density[x][y] = colors;
    }
  }
 
  // determine total particles to create;
  int particlesum = 0;
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 particlesum += density[x][y];
    }
  }
  psum = particlesum;
 
  // create the particle field
  background(255);
  particle p[] = new particle[particlesum];
  int z = 0;
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 if(density[x][y] != 0){
   int thisdensity = density[x][y];
   for(int particlebirth = 0; particlebirth < thisdensity; particlebirth++){
     p[particlebirth] = new particle(x,y,z);
     p[particlebirth].update();
   }
 }
    }
  }
}
 
// ---------------------------------------------------
void loop() // MAIN SOFTWARE LOOP
{
  for (int i = 0; i < psum; i++){
    int newx = p[i].getxloc() + int(random(-3, 3));
    int newy = p[i].getyloc() + int(random(-3, 3));
    int newz = p[i].getzloc() + int(random(-3, 3));
    p[i] = new particle(newx,newy,newz);
    p[i].update();
  }
}
 
// ---------------------------------------------------
class particle {
  int xloc, yloc, zloc;
  particle(int x, int y, int z) {
    xloc = x;
    yloc = y;
    zloc = z;
  }
  void update() {
    color c = color(0,0,0,1);
    stroke(c);
    point(xloc, yloc, zloc);
  }
 
}
 
arielm

WWW
Re: ... over my head?
« Reply #1 on: Jan 27th, 2004, 12:39am »

i didn't compile your code in p5, but i can see a problem from here, in the following:
Code:
int newx = p[i].getxloc() + int(random(-3, 3));

where is the getxloc() method? it is supposed to be a member of the Particle class, but i can't find it...
 

Ariel Malka | www.chronotext.org
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #2 on: Jan 27th, 2004, 1:06am »

Ugh - I took out getxloc() when it wasnt working --
inside the particle class, I had
Code:

int getxloc(){
 return(xloc);
}

 
What I was trying to do was get and modify the value for xloc, yloc, and zloc from each particle object.
 
The line that you are saying doesn't work was initially attempted as something like p[i].xloc + ...
 
But I guess I cant just stick the variable name on the end of an object in order to reference and modify that variable inside of the object?
 
Charles
 
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #3 on: Jan 27th, 2004, 1:22am »

Here is what I was trying... I don't understand why this doesn't work. I get a NullPointer Exception on the same line that you pointed out, Ariel.
 
 
Code:

// User Control Variables
String imagename = "digidust.jpg"; // Source Image
 
//Global Variables
particle p[];
int psum = 0;
 
// ------------------------------------------------------
void setup() // SET UP SOFTWARE
{
  // create the Processing environment
  size(200,200);
  framerate(30);
  smooth();
  background(255);
 
  // load an image from the user variable "imagename"
  BImage startimage;
  startimage = loadImage(imagename);
  image(startimage, 0, 0);
 
  // convert loaded image to greyscale and spit it upon the screen
  color c1 = get(0,0);
  color c2 = get(0,0);
  float bright = brightness(c1);
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 colorMode(HSB);
 c1 = get(x,y);
 bright = brightness(c1);
 colorMode(RGB);
 c2 = color(bright, bright, bright);
 set (x,y,c2);
    }
  }
 
  // create density array -  white = 0 and black = 255.
  int[][] density = new int[width][height];
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 int colors = get(x,y) & 0xff;
 colors = 100-int(colors/2.55);
 //c1 = 255-c1;
 density[x][y] = colors;
    }
  }
 
  // determine total particles to create;
  int particlesum = 0;
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 particlesum += density[x][y];
    }
  }
  psum = particlesum;
 
  // create the particle field
  background(255);
  particle p[] = new particle[particlesum];
  int z = 0;
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 if(density[x][y] != 0){
   int thisdensity = density[x][y];
   for(int particlebirth = 0; particlebirth < thisdensity; particlebirth++){
     p[particlebirth] = new particle(x,y,z);
     p[particlebirth].update();
   }
 }
    }
  }
}
 
// ------------------------------------------------------
void loop() // MAIN SOFTWARE LOOP
{
  for (int i = 0; i < psum; i++){
    p[i].xloc += int(random(-3, 3));
    p[i].yloc += int(random(-3, 3));
     p[i].zloc += int(random(-3, 3));
    p[i].update();
  }
}
 
// ------------------------------------------------------
class particle {
  int xloc, yloc, zloc;
  particle(int x, int y, int z) {
    xloc = x;
    yloc = y;
    zloc = z;
  }
 
  void update() {
    color c = color(0,0,0,1);
    stroke(c);
    point(xloc, yloc, zloc);
  }
 
}
 
benelek

35160983516098 WWW Email
Re: ... over my head?
« Reply #4 on: Jan 27th, 2004, 1:48am »

actually, you can use the following - you don't need any methods to help you access those variables. this will work fine:
 
Code:
int newx = p[i].xloc + int(random(-3, 3));

 
i think the problem might be that you're trying to access a member of the p[] array that doesn't exist. i didn't have time to go through the code to find out what the variable psum is, but i wouldn't be surprised if that's where the problem is. try using p.length instead of psum, for the following line in loop:
 
Code:
for (int i = 0; i < psum; i++){

 
 
also (after running your code), there're a number of other problems. for instance, you have defined a global array p[] outside setup() but defined a local array p[] within setup(). and in loop(), you don't need to define new particle objects each time. you only need to change the xloc,yloc,zloc vaiables within the existing particle objects.
 
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #5 on: Jan 27th, 2004, 1:55am »

on Jan 27th, 2004, 1:48am, benelek wrote:
i think the problem might be that you're trying to access a member of the p[] array that doesn't exist.......for instance, you have defined a global array p[] outside setup() but defined a local array p[] within setup().  

 
ok, then that brings me back to my initial problem with this...
i don't know how long p[] needs to be until setup(), since it will vary based on the loaded picture, but I need to access it in loop(). I thought that I had solved it, but I guess I didn't.
 
Any tips
 
Charles
 
benelek

35160983516098 WWW Email
Re: ... over my head?
« Reply #6 on: Jan 27th, 2004, 2:01am »

you can define that an object exists outside setup(), but not define what it is. like this:
 
Code:
int num;
void setup() {
  num=5;
}
void draw() {
  println(num);
}

 
however, this is completely different, and is not what you're trying to do:
 
Code:
int num;
void setup() {
  int num=5;
}
void draw() {
  println(num);
}

 
it's a small difference in code, but a huge difference in effect.
 
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #7 on: Jan 27th, 2004, 2:27am »

ok, so I get that...
 
so, globally, I do this:
particle[] p;
 
Then, in setup(), I do this:
p = new particle[particlesum];
 
And then in loop(), I should do this:
p[i].xloc += int(random(-3, 3));
 
But I still get an error on that line... p[] doesn't seem to exist at that point.
 
So, I looked back at an example on the Processing site.
 
globally REAS did:
Module[] mods;
isn't that particle[] p; ?
 
In Setup:
mods = new Module[num];  
p = new particle[particlesum]; should be the same.
 
I'm stumped.
 
 
kevinP

Email
Re: ... over my head?
« Reply #8 on: Jan 27th, 2004, 11:14am »

Hi,
 
> And then in loop(), I should do this:  
> p[i].xloc += int(random(-3, 3));
 
You didn't mention the error message, but when I tried one of your versions last night after converting your xloc() function to a variable as you have it here, I got a null pointer error; then I went to bed.
 
My experience is limited, but it seems that I usually get this error in association with an array when I've either tried to read/write beyond its length or reading a particular array location that has not been initialized. (You can say it now: thanks, I knew that).
 
Are you sure that "p[i].xloc" has a value before you modify it?
 

Kevin Pfeiffer
fry


WWW
Re: ... over my head?
« Reply #9 on: Jan 27th, 2004, 12:35pm »

on Jan 27th, 2004, 2:27am, Charles Hinshaw wrote:
so, globally, I do this:
particle[] p;
 
Then, in setup(), I do this:
p = new particle[particlesum];
 
And then in loop(), I should do this:
p[i].xloc += int(random(-3, 3));

you have to create each new particle.. so in setup(), you need to do:
 
// this just creates an array of type particle, with length particlesnum
p = new particle[particlesnum];
// this creates a particle objects themselves
for (int i = 0; i < particlesnum; i++) {
  p[i] = new particle();
}
 
this can be confusing at first glance. basically there are two levels, first you create the array using "new", then you fill it with particle goodness, also using "new".
 
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #10 on: Jan 27th, 2004, 6:36pm »

So... I went through my code, cleaning everything up and adding comments to things in order to figure them out, and it turns out that when filling my array with particle goodness, I was using the pixel density rather than an over all density, so, now I have it fixed and my little particle friends are doing what I ask of them.
 
brownian() is just a test -- 3D brownian motion isn't really of any interest. The next step is to start getting the particles to behave in interesting manners. Ultimately, I would like to build this as a transition from one image to another (particles cloud out and reform the second image)...
 
Anyway, the new (working) code is below. If anybody wants to try it out, I would suggest using an image with isolated areas of darkness on a light background -- a word written in black on a white field seems to work really well.
 
Thanks to everyone for their help.
 
Code:

// User Control Variables
String imagename = "digidust.jpg"; // Source Image
 
//Global Variables
particle p[]; // create p as an array of object particle
// ------------------------------------------------------
void setup()
{
  size(200,200);
  background(255);
  smooth();
  BImage startimage;
  startimage = loadImage(imagename);
  image(startimage, 0, 0);
 
  // convert loaded image to greyscale and spit it upon the screen
  color c1 = get(0,0);
  color c2 = get(0,0);
  float bright = brightness(c1);
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 colorMode(HSB);
 c1 = get(x,y);
 bright = brightness(c1);
 colorMode(RGB);
 c2 = color(bright, bright, bright);
 set (x,y,c2);
    }
  }
 
  // create density array -  white = 0 and black = 255.
  int[][] density = new int[width][height]; // create 2D array "density" the size of the screen
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 int colors = get(x,y) & 0xff; // pull a color from the pixel location and slice it open
 colors = 100-int(colors/2.55); // invert the color and scale it to 0-100
 density[x][y] = colors; // write teh value into density at the pixel's location
    }
  }
 
  // determine total particles to create;
  int particlesum = 0; // we will call our total particles "particlesum"
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 particlesum += density[x][y]; // add up the density value of each x,y location
    }
  }
 
  // create the particle field
  background(255);
  p = new particle[particlesum]; // create array "p" of type "particle" with a length of "particlesum"
  int z = 0;
  int iteration = 0; // this will be our iteration counter
  for (int x = 0; x < width; x++){
    for (int y = 0; y < height; y++){
 if(density[x][y] != 0){
    for(int i = 0; i < density[x][y]; i++){ // at each x,y, create particles from density
    p[iteration] = new particle(x,y,z); // create each particle
    p[iteration].paint(); // draw the particle
    iteration++; // add one to iteration
   }
 }
    }
  }
}
 
// ------------------------------------------------------
void loop() // MAIN SOFTWARE LOOP
{
background(255);
  for(int i = 0; i < p.length; i++)  {
    p[i].brownian();
    p[i].paint();
  }
 
}
 
// ------------------------------------------------------
class particle {
  int xloc, yloc, zloc;
  particle(int x, int y, int z) {
    xloc = x;
    yloc = y;
    zloc = z;
  }
  void paint() {
    color c = color(0,0,0,1);
    stroke(c);
    point(xloc, yloc, zloc);
  }
  void brownian() {
    xloc += random(-3,3);
    yloc += random(-3,3);
    zloc += random(-3,3);
}
}
 
kevinP

Email
Re: ... over my head?
« Reply #11 on: Jan 27th, 2004, 8:01pm »

Hi Charles,
 
now you can help!
 
You wrote:
colors = get(x,y) & 0xff; // pull a color from the pixel location and slice it open
 
What is this doing? I saw that it (the "& 0xff") changed a value of 255 to 100. Some sort of bit operation Or?
 
[Follow-up]
 
Okay, I see that get is giving me values such as "-16645630" and that this is being converted to 2, etc. (Perhaps the reference entry for get, etc. should mention this?)
 
Thanks!
 
-K
« Last Edit: Jan 27th, 2004, 8:37pm by kevinP »  

Kevin Pfeiffer
Charles Hinshaw
Guest
Email
Re: ... over my head?
« Reply #12 on: Jan 27th, 2004, 8:57pm »

what I was doing there was hacking off the bits that I didnt need from the pixel color. remember that I am dealing with colors that have the same R, G, and B values (I made sure of that earlier, in case an image wasnt really all gray) so it doesnt matter if I had pulled the last eight bits of inforamtion (Blue) or if I had shifted (>> 16) to get the red.
 
Did I need to do it this way? Probably not... But this is the first thing I have created in Processing, so I wanted to try a variety of techniques.
 
The part that made the color drop to 1-100 was dividing it by 2.55. I also took that and subtracted it from 100 to get create my "density".
 
 
kevinP

Email
Re: ... over my head?
« Reply #13 on: Jan 27th, 2004, 10:49pm »

It was this part: "& 0xFF" that tripped me up. I only pretend to know something about programming. I looked it up -- bitwise AND -- I've heard of it but never used it. Now I see that it just pulls the last 8 binary places (or the last 8-bit RGB value) from get's return value.
 
And I see know (calculator handy) that "& 0xFF00" would give me the G value. Cool.
 
I think the Processing reference page should/could say more about this.
 
Txs,
« Last Edit: Jan 27th, 2004, 10:53pm by kevinP »  

Kevin Pfeiffer
arielm

WWW
Re: ... over my head?
« Reply #14 on: Jan 28th, 2004, 1:05am »

on Jan 27th, 2004, 10:49pm, pfeiffer wrote:
And I see know (calculator handy) that "& 0xFF00" would give me the G value

almost! (in addition of bit masking, you also need bit shifting)
 
say, if c is an integer with a bit packed color value inside,
 
r: c & 0xff
g: (c & 0xff00) >> 8
b: (c & 0xff0000) >> 16
 

Ariel Malka | www.chronotext.org
Pages: 1 2 

« Previous topic | Next topic »