# Problem with passing vectors to next

Hi,
I have been working on an idea a while ago and want to pick up where I left. What I want to create is some kind of self-generating irregular pattern, existing of different polygons.
I wrote the code for a random polygon, which worked.

Where I’m stuck is: I want to start the NEXT polygon in one of the corners of the previous one. So I need to pass those coordinates. I’m not succeeding in doing that.

The sketch is here: https://www.openprocessing.org/sketch/310023

There is another small problem, on OpenProcessing, the sketch works, but in Processing on my Mac, I get a NullPointerExeption for polygon.x (while that should have value 300??)

(j=0, so nextpolygon is assigned the value (300, 300). I added the print-statement to narrow down the problem, at first, the exception was in the next line with nextpolygon.x)

``````Polygon[] polygon = new Polygon[1];
PVector endcorner, nextpolygon;

int j=0;

void draw() {

if (j==0) {                // the first time, when j=0, start at the center
PVector nextpolygon = new PVector(300, 300);
} else if (j>0) {              // after that, start
PVector nextpolygon = polygon[j].endCorner();
}

println(nextpolygon.x);
``````

I found that your code does not run in to an exception when I comment line 27, even though both endCorner and nextPolygon are already initialized

``````while (nextpolygon.x<width) {                     // stop drawing polygons when the edge of the screen is reached
polygon[j] = new Polygon(nextpolygon);
polygon[j].build();
polygon[j].display();
polygon = (Polygon[])expand(polygon, polygon.length+1);
j++;
//println(endcorner.x +" "+ nextpolygon.x + " " + " " +polygon.length);**
}
``````

I’m still working out a solution to get the polygons to reach the end of the screen, however

Edit: I found that if you initialize endcorner in setup, the code never finishes compiling and you just get a white screen

Hi BennyHacker,

Thank you for your help. I saw that I sometimes wrote “endCorner” and sometimes “endcorner”. I corrected that, but it didn’t solve the problem.

The error I got on OpenProcessing is “TypeError: endcorner is null”, but it draws a polygon (and prints “300” beneath the screen. When I comment 27 out, after a while I get the orange background and much polygons drawn on the same place.

In Processing the error is “NullPointerException”, and I only get an orange background and the sketch gets stuck. This is the same when I comment line 27 out.

“endcorner”= 0 because the returning doesn’t work. It never gets to line 65, because the println is not executed…

I’ll search further tomorrow!

Gladly! One other thing… I noticed the way you were going to be drawing these shapes seems kinda mathy and complex so I did a quick google search and apparently there’s a method called a Voronoi Diagram

The implementation in processing was actually very easy:

``````float radius;
ArrayList<Seed> seeds;
boolean hasWhite = false;
boolean update=true;
void setup() {
size(600, 600);
seeds = new ArrayList<Seed>();
int r = 28;
for (int i = 0; i < r; i++) {
Seed s = new Seed();
seeds.add(s);
}
background(255);
}
void mouseReleased() {
seeds = new ArrayList<Seed>();
update=true;
int r = (int)random(15, 35);
for (int i = 0; i < r; i++) {
Seed s = new Seed();
seeds.add(s);
}
radius=0;
background(255);
}
void draw() {
hasWhite=false;
if (update) {
//iterate through screen pixels
for (int k = 0; k < width; k++) {
for (int l = 0; l < height; l++) {
//check if pixel is white
if (get(k, l)==color(255)) {
hasWhite=true;
//if so, iterate through circles
for (int i = 0; i < seeds.size(); i++) {
//check if pixel is within the circle's radius
if (dist(k, l, seeds.get(i).pos.x, seeds.get(i).pos.y)<radius) {
//if so, give it a color
set(k, l, seeds.get(i).c);
}
}
}
}
}
//increase radius every frame
radius+=.25;
//stop updating once all white pixels are gone
update=hasWhite;
}
}
class Seed {
PVector pos = new PVector(random(width), random(height));
color c = color(random(45, 245), random(45, 245), random(45, 245));
}
``````

Although since you’re trying to make your own unique algorithm I encourage you to keep at it

2 Likes

You’re declaring local variable nextpolygon inside the `if () / else` code block.

It means that variable is scoped inside that curly braces block and ceases to exist once that block finishes!

2 Likes

That’s indeed interesting! But you’re also right: I want to create my own sketch . It’s a bit different from that Voronoi diagram, I want the second polygon to start in a corner of the first polygon, and so on. If it’s possible that on more then one corner a new polygon starts.

So a next step will also be, avoiding that new polygons overlap with the existing ones.

(I’m not native English, is it a little understandable what I’m saying?)

I declare it in the setup, no? But indeed, I don’t give it a value. The whole purpose of this:

``````  if (j == 0) {                // the first time, when j=0, start at the center
PVector nextpolygon = new PVector(300, 300);
} else if (j > 0) {          // after that, start
PVector nextpolygon = polygon[j].endCorner();
}
``````

Is to give a value on the first vector. Maybe it’s made to complex to achieve this?
EDIT:
Okay, to solve the problem, I changed the if/else if statement in an if statement, so I could move

``````PVector nextpolygon = polygon[j].endCorner();
``````

outside that code block. But wherever I put it, it gives trouble.

Ok, I moved nextpolygon elsewhere, and I don’t have the NullPointException anymore. Now I get the message “The value of the local variable nextpolygon is not used”.

``````Polygon[] polygon = new Polygon[1];
PVector endcorner;
PVector nextpolygon = new PVector(300, 300);
int j=0;

void setup() {
size(600, 600);
background(204, 100, 30);
}

void draw() {

println(j);

if (j>0) {
PVector nextpolygon = polygon[j].endcorner();
}

while (nextpolygon.x<width) {                     // stop drawing polygons when the edge of the screen is reached
polygon[j] = new Polygon(nextpolygon);
polygon[j].build();
polygon[j].display();
polygon = (Polygon[])expand(polygon, polygon.length+1);
j++;
// println(endcorner.x +" "+ nextpolygon.x + " " + " " +polygon.length);
}

noLoop();
}

class Polygon {
PVector endcorner = new PVector();
PVector firstcorner = new PVector();
PVector[] points;

Polygon(PVector start) {
firstcorner.set(start);
}

void build() {
int numbercorners= int(random(3, 8));           // select number of corners between 3 and 8
float t = 360/numbercorners;                    // = 120, 90, 72, 60, 51.x, 45
points = new PVector[numbercorners];            // create an array to store the vectors of each corner
float rotation = random(0, 2 * PI);             // = PI/5 = 36°
points[0] = new PVector(firstcorner.x, firstcorner.y);
for (int i=1; i < numbercorners; i++) {        // calculate the vectors for each corner of the polygon
// i * t would generate a regular polygon, therefor adding random amount 'rotation'
float xcorner = firstcorner.x + cos((radians(i * t)+rotation)) * (random(12, 30)); // the random number is the length of a side
float ycorner = firstcorner.y + sin((radians(i * t)+rotation)) * (random(12, 30));
points[i] = new PVector(xcorner, ycorner);
}
}

void display() {         // draw the polygon
beginShape();
for (int i = 0; i < points.length; i++) {
vertex(points[i].x, points[i].y);
}
endShape(CLOSE);

ellipse(points[points.length-1].x, points[points.length-1].y, 6, 6);   // this is temporary, to see the last corner
}

PVector endcorner() {             // pass the last vector to the next polygon
int i = int(points.length-1);

println(points[i].x+" "+" "+points[i].y);

PVector endcorner = new PVector(points[i].x, points[i].y); // this passes the x and y values of the last point

println(endcorner.x+" "+" "+endcorner.y);

return endcorner;
}
}
``````

I don’t understand, in line 19 and 20, nextpolygon is used!

On line 16, similar to what GoToLoop said, try removing the PVector constructor and just write:

nextpolygon = polygon[j].endcorner();

@BennyHacker, that doesn’t work, the first time there is no endcorner.

I added some print-commands to see where it goed wrong and somehow the returning function never gets activated (or run or called).

``````Polygon[] polygon = new Polygon[1];
PVector endcorner;
PVector nextpolygon = new PVector(300, 300);
int j=0;

void setup() {
size(600, 600);
background(204, 100, 30);
}

void draw() {

println(j);

if (j>0) {
PVector nextpolygon = polygon[j].endcorner();
}

while (nextpolygon.x<width) {                     // stop drawing polygons when the edge of the screen is reached
println("Keep drawing polygons");
polygon[j] = new Polygon(nextpolygon);
polygon[j].build();
polygon[j].display();
polygon = (Polygon[])expand(polygon, polygon.length+1);
j++;
// println(endcorner.x +" "+ nextpolygon.x + " " + " " +polygon.length);
}

noLoop();
}

class Polygon {
PVector endcorner = new PVector();
PVector firstcorner = new PVector();
PVector[] points;

Polygon(PVector start) {
firstcorner.set(start);
}

void build() {

println("Building polygons");

int numbercorners= int(random(3, 8));           // select number of corners between 3 and 8
float t = 360/numbercorners;                    // = 120, 90, 72, 60, 51.x, 45
points = new PVector[numbercorners];            // create an array to store the vectors of each corner
float rotation = random(0, 2 * PI);             // = PI/5 = 36°
points[0] = new PVector(firstcorner.x, firstcorner.y);
for (int i=1; i < numbercorners; i++) {        // calculate the vectors for each corner of the polygon
// i * t would generate a regular polygon, therefor adding random amount 'rotation'
float xcorner = firstcorner.x + cos((radians(i * t)+rotation)) * (random(12, 30)); // the random number is the length of a side
float ycorner = firstcorner.y + sin((radians(i * t)+rotation)) * (random(12, 30));
points[i] = new PVector(xcorner, ycorner);
}
}

void display() {         // draw the polygon

println("drawing polygons");

beginShape();
for (int i = 0; i < points.length; i++) {
vertex(points[i].x, points[i].y);
}
endShape(CLOSE);

ellipse(points[points.length-1].x, points[points.length-1].y, 6, 6);   // this is temporary, to see the last corner
}

PVector endcorner() {             // pass the last vector to the next polygon

println("Passing vector");

int i = int(points.length-1);

println(points[i].x+" "+" "+points[i].y);

PVector endcorner = new PVector(points[i].x, points[i].y); // this passes the x and y values of the last point

println(endcorner.x+" "+" "+endcorner.y);

return endcorner;
}
}
``````

I understand what you’re saying, but I’m trying like crazy and I can’t figure out to solve the problem! I need the if-statement to check if it’s the first polygon. Only when it’s not, I want to pass vector “endcorner” to “nextolygon”.
I tried putting the if-statement inside and around the while-statement, but that’s not the solution.

Declare that variable outside the `if () / else` code block scope.
Then you can assign a value to it inside the `if () / else` code block scope.

Processing.org/examples/variablescope.html

I thought I declared it at the top, before my setup().

If a variable is already declared as a global field, when we redeclare it in a local scope, we overshadow it in that scope!

2 Likes

I’m sorry, I was not at home and answered a little to soon, as I already mentioned, the NullPointException problem was already gone. I guess the declaration is OK like it is. The new trouble is that the variable is not used, while it is used 2 lines after the if-statement.

• Maybe the scope of that variable is again the culprit? I tried declaring nextpolygon inside the void draw() but that didn’t help. Also putting the “while” part inside the “if” brackets didn’t work (it was worse).
• Is it because I use nextpolygon.x in stead of the PVector? Then it is better to return nextpolygon.x and nextpolygon.y and then recompose the PVector. IF I have time tomorrow, I’ll test that.

Already a big thanx for your advice @GoToLoop and @BennyHacker

My advice is that you should stick to debug your sketch under PDE’s Java Mode.
Debugging code under a browser, especially for a code transpiled from Java to JS, is much worse!

I’m working in Processing on my Macbook, the openprocessing sketch is just to share it.
Error mentioned: “The value of the local variable “nextpolygon” is not used”, line 16.

Console:

``````Keep drawing polygons
Building polygons
drawing polygons
Keep drawing polygons
Building polygons
drawing polygons
Keep drawing polygons
Building polygons
drawing polygons
Keep drawing polygons
Building polygons
drawing polygons
...
``````

This is not an error but merely a warning!

However, since you had already declared variable nextpolygon as a global field, it should never be a local variable unless you redeclared it as a local variable (or as a function parameter) as well!

I removed the “while” statement to avoid variablescope problems there (I’ll add new statements to avoid drawing of-screen after this problem is solved).
Then I keep getting the “nextpolygon is not used” warning. I really don’t understand!! I use it clearly: " polygon[j] = new Polygon(nextpolygon);" and now it is in the same scope, so that’s not the trouble anymore.
Somehow the sketch never goes beyond j=1 either. For that, I removed the while and the endloop. But it didn’t solve the problem.

``````Polygon[] polygon = new Polygon[1];
PVector endcorner;
PVector nextpolygon = new PVector(300, 300);
int j=0;

void setup() {
size(600, 600);
background(204, 100, 30);
}

void draw() {

if (j>0) {
PVector nextpolygon = polygon[j].endcorner();   // give nextpolygon the value of the last vector "endcorner"
}                                                 // this function is part of the Polygon-class

println("nextpolygon="+nextpolygon);

polygon[j] = new Polygon(nextpolygon);
polygon[j].build();
polygon[j].display();
polygon = (Polygon[])expand(polygon, polygon.length+1);
j++;

println("j="+j);
}

class Polygon {
PVector endcorner = new PVector();
PVector firstcorner = new PVector();
PVector[] points;

Polygon(PVector start) {
firstcorner.set(start);
}

void build() {

println("Building polygon");

int numbercorners= int(random(3, 8));           // select number of corners between 3 and 8
float t = 360/numbercorners;                    // = 120, 90, 72, 60, 51.x, 45
points = new PVector[numbercorners];            // create an array to store the vectors of each corner
float rotation = random(0, 2 * PI);             // = PI/5 = 36°
points[0] = new PVector(firstcorner.x, firstcorner.y);
for (int i=1; i < numbercorners; i++) {         // calculate the vectors for each corner of the polygon
// i * t would generate a polygon with the same rotation between each corner,
// therefor adding random amount 'rotation'
// firstcorner is the center of a polygon
float xcorner = firstcorner.x + cos((radians(i * t)+rotation)) * (random(12, 30)); // x= a + r.cosθ, y= b + rsinθ
// r is the distance from the center to the corner, here: (random(12, 30)
// a and b are coordinates of the center of the polygon
float ycorner = firstcorner.y + sin((radians(i * t)+rotation)) * (random(12, 30)); //
points[i] = new PVector(xcorner, ycorner);
}
}

void display() {         // draw the polygon

println("drawing polygon");

beginShape();
for (int i = 0; i < points.length; i++) {
vertex(points[i].x, points[i].y);
}
endShape(CLOSE);

ellipse(points[points.length-1].x, points[points.length-1].y, 6, 6);   // this is temporary, to see the last corner
}

PVector endcorner() {             // pass the last vector to the next polygon

println("Passing vector");

int i = int(points.length-1);

println(points[i].x+" "+" "+points[i].y);

PVector endcorner = new PVector(points[i].x, points[i].y); // this passes the x and y values of the last point

println(endcorner.x+" "+" "+endcorner.y);

return endcorner;
}
}
``````

Second version, where I tried to initialize in the if/else statement, gives the nullpointexception error again. I don’t understand at all!

``````Polygon[] polygon = new Polygon[1];
PVector endcorner, nextpolygon;
int j=0;

void setup() {
size(600, 600);
background(204, 100, 30);
}

void draw() {

if (j==0) {
PVector nextpolygon = new PVector(300, 300);
}
else {
PVector nextpolygon = polygon[j].endcorner();   // give nextpolygon the value of the last vector "endcorner"
}                                                 // this function is part of the Polygon-class

println("nextpolygon="+nextpolygon);

polygon[j] = new Polygon(nextpolygon);
polygon[j].build();
polygon[j].display();
polygon = (Polygon[])expand(polygon, polygon.length+1);
j++;

println("j="+j);
}

class Polygon {
PVector endcorner = new PVector();
PVector firstcorner = new PVector();
PVector[] points;

Polygon(PVector start) {
firstcorner.set(start);
}

void build() {

println("Building polygon");

int numbercorners= int(random(3, 8));           // select number of corners between 3 and 8
float t = 360/numbercorners;                    // = 120, 90, 72, 60, 51.x, 45
points = new PVector[numbercorners];            // create an array to store the vectors of each corner
float rotation = random(0, 2 * PI);             // = PI/5 = 36°
points[0] = new PVector(firstcorner.x, firstcorner.y);
for (int i=1; i < numbercorners; i++) {         // calculate the vectors for each corner of the polygon
// i * t would generate a polygon with the same rotation between each corner,
// therefor adding random amount 'rotation'
// firstcorner is the center of a polygon
float xcorner = firstcorner.x + cos((radians(i * t)+rotation)) * (random(12, 30)); // x= a + r.cosθ, y= b + rsinθ
// r is the distance from the center to the corner, here: (random(12, 30)
// a and b are coordinates of the center of the polygon
float ycorner = firstcorner.y + sin((radians(i * t)+rotation)) * (random(12, 30)); //
points[i] = new PVector(xcorner, ycorner);
}
}

void display() {         // draw the polygon

println("drawing polygon");

beginShape();
for (int i = 0; i < points.length; i++) {
vertex(points[i].x, points[i].y);
}
endShape(CLOSE);

ellipse(points[points.length-1].x, points[points.length-1].y, 6, 6);   // this is temporary, to see the last corner
}

PVector endcorner() {             // pass the last vector to the next polygon

println("Passing vector");

int i = int(points.length-1);

println(points[i].x+" "+" "+points[i].y);

PVector endcorner = new PVector(points[i].x, points[i].y); // this passes the x and y values of the last point

println(endcorner.x+" "+" "+endcorner.y);

return endcorner;
}
}
``````

When a datatype (PVector in this case) is placed before a variable it is called a variable declaration.

Docs.Oracle.com/javase/tutorial/java/nutsandbolts/variables.html