Hello folks! I have a big question for you:

I am creating a code which when you press keyboard then processing creates a random convex polygon but I am really struggling finding the right way.

thanks

Hello folks! I have a big question for you:

I am creating a code which when you press keyboard then processing creates a random convex polygon but I am really struggling finding the right way.

thanks

1 Like

Hi @rioma7!

You can generate a random set of points using your preferred random generator ( `PVector.random2D`

, `random()`

, or `randomGaussian()`

) and apply convex hull algorithm to the points. Check out the wikipedia entry for QuickHull pseudocode.

If you just want a regular polygon function, check the example in processing under Basics > Form > Regular Polygon

1 Like

Passing parameters to create a regular polygon is one of the examples of creating your own function â€“ `polygon()`

â€“ on the Processing website. You can see it here:

1 Like

In the code linked by @jeremydouglass the angles are evenly spaced, so you get regular polygons. If you would like irregular polygons do randomize the angles. Maybe like this:

- create an
`array`

containing 3 or more floats between 0 and TWO_PI (the angles) - sort that
`array`

- iterate through the
`array`

of angles and add a vertex for each angle

If you do this on a frame by frame basis, the polygon will jitter, because you get a new random polygon in each frame. You can avoid the jitter by â€śstoringâ€ť the generated polygon in a `PShape`

, probably inside `setup`

, and then drawing that `PShape`

inside `draw`

.

I made a small program to do this, but I better donâ€™t spoil the exercise by posting the code

5 Likes

@jeremydouglass / @hamoid thanks guys. Now I try to find out a solution otherwise I will ask you again

@hamoid I need your help

I cannot find a solution, I have tried a lot of stuff but never finding a solution!!!

This is the thing I wrote:

```
PShape shapes[] = new PShape[64];
void setup() {
size(600, 600, P2D);
noStroke();
fill(70);
for (int i=0; i<shapes.length; i++) {
shapes[i] = polygon(30, (int)random(3, 10));
}
}
void draw() {
background(255);
for (int i=0; i<shapes.length; i++) {
pushMatrix();
// put the polygons in a grid
translate(map(i%8, 0, 7, 50, 550), map(i/8, 0, 7, 50, 550));
// make them rotate at different speeds
rotate(frameCount / (50.0 + 10 * i));
shape(shapes[i]);
popMatrix();
}
}
PShape polygon(float radius, int npoints) {
// create a random list of angles
float angles[] = new float[npoints];
for(int i=0; i<npoints; i++) {
angles[i] = random(TWO_PI);
}
// sort the list
angles = sort(angles);
// create a shape with those angles
PShape s = createShape();
s.beginShape();
for (float a : angles) {
float sx = cos(a) * radius;
float sy = sin(a) * radius;
s.vertex(sx, sy);
}
s.endShape(CLOSE);
return s;
}
```

2 Likes

thanks @hamoid

Now I was trying to create only one shape when I **KeyPressed();** but I donâ€™t know how to do it because if I put everything inside

```
if(keyPressed){
for (int i=0; i<shapes.length; i++) {
pushMatrix();
translate(map(i%8, 0, 7, 50, 550), map(i/8, 0, 7, 50, 550));
shape(shapes[i]);
popMatrix();
}
PShape polygon(float radius, int npoints) {
// create a random list of angles
float angles[] = new float[npoints];
for(int i=0; i<npoints; i++) {
angles[i] = random(TWO_PI);
}
// sort the list
angles = sort(angles);
// create a shape with those angles
PShape s = createShape();
s.beginShape();
for (float a : angles) {
float sx = cos(a) * radius;
float sy = sin(a) * radius;
s.vertex(sx, sy);
}
s.endShape(CLOSE);
return s;
}
```

it doesnâ€™t work and I also didnâ€™t understand how can I move the polygon in the middle of the screen to export in PDF.

The example above was creating an array of 64 shapes. If you only need one, you donâ€™t need that array, and you donâ€™t need the for loop to iterate 64 times creating and drawing all shapes. You just need one I assume.

You can keep the polygon function, which just returns a shape with a polygon. The following example creates and draws a polygon every time you press a key:

```
void setup() {
size(600, 600, P2D);
background(255);
}
void draw() {
}
void keyPressed() {
noStroke();
fill(random(255));
PShape shp = polygon(200, (int)random(3, 10));
translate(width * 0.5, height * 0.5); // move to the center of the screen
rotate(random(TWO_PI)); // random rotation
shape(shp); // draw the polygon
}
PShape polygon(float radius, int npoints) {
// create a random list of angles
float angles[] = new float[npoints];
for (int i=0; i<npoints; i++) {
angles[i] = random(TWO_PI);
}
// sort the list
angles = sort(angles);
// create a shape with those angles
PShape s = createShape();
s.beginShape();
for (float a : angles) {
float sx = cos(a) * radius;
float sy = sin(a) * radius;
s.vertex(sx, sy);
}
s.endShape(CLOSE);
return s;
}
```

Notice that it assigns a random gray color to each polygon, this way you can notice the overlapping polygons. But of course you can change this.

Also notice that the polygon function takes two arguments: first, the radius of the polygon, and second, the number of points it should have.

1 Like

An image to help understand what this polygon function does:

The `polygon`

function receives two arguments: a radius (to set how large the polygon should be) and a number of points. In the image you see 4 examples with 3, 4, 5 and 5 points.

The `polygon`

function first creates an array of angles, each value in that array being between 0 and TWO_PI.

```
float angles[] = new float[npoints];
for (int i=0; i<npoints; i++) {
angles[i] = random(TWO_PI);
}
```

That range contains all possible angles in a circle, as you can see in this image in the outer ring of values that goes 0 0.1 0.2 0.3 â€¦ 6.0 6.1 6.2:

Letâ€™s say we asked for a polygon with 5 points, and our `angles[]`

array contains these random numbers:

4.2 1.3 3.0 0.5 5.9. We will use the angles to find 2D points in a circle, by using `sin()`

and `cos()`

, and then connect those points.

The red shape in the image shows what can happen if you forget to sort the list of random angles: you may get a strange shape. By sorting the angles you make sure the angles are either clockwise or counterclockwise and avoid such strange shapes.

```
angles = sort(angles);
```

The second part of the `polygon`

function creates a shape and adds one by one points using the sorted angles. To convert an angle to a 2D point we use `cos()`

and `sin()`

. Those two functions return numbers between -1 and +1, which would be a very small polygon. Thatâ€™s why we multiply the values by radius, so the polygon can have coordinates between -radius and +radius.

```
PShape s = createShape();
s.beginShape();
for (float a : angles) {
float sx = cos(a) * radius;
float sy = sin(a) * radius;
s.vertex(sx, sy);
}
s.endShape(CLOSE);
return s;
```

2 Likes

Hallo guys!!! Unfortunately I need more helpâ€¦

my project is changed a bit and now basically is to create a shape using the data from the audio frequency!

So read the audio frequency (between 20Hz to 20kHz) and if [X is the read frequency by the microphone]

if **x >= 9990Hz**

draw a random polygon in a random position on the screen

long and narrow

with inside angles =< 90Â°

if **x=<9990Hz**

draw a random polygon in a random position on the screen

flat and wide

with angles =>90Â°

I only need how to draw the polygonsâ€¦the polygon should be convex or concave

I hope you can help me!

If concave polygons are ok, you can randomize the radius with something like this:

```
for (float a : angles) {
float r = radius * random(0.7, 1.3);
float sx = cos(a) * r;
float sy = sin(a) * r;
s.vertex(sx, sy);
}
```

That way they points no longer fall in a circle, some are farther from the center, others are closer.

One way to make long shapes would be to choose the angles in a way that they are near two opposing locations in a circle. 0 and `PI`

are opposed (0 and 180 degrees). So you could randomly choose either 0 or `PI`

, and then add some randomness around that:

```
angles[i] = int(random(2)) * PI + random(0.8);
```

`int(random(2))`

gives either 0 or 1. Multiplied by `PI`

you get either 0 or `PI`

. Then add some randomness so you do NOT only get 0 or `PI`

, but numbers around 0 and numbers around `PI`

.

But there are maaaany ways to create shapes. I suggest you make some drawings and then think how they could be created, or post the drawings and people can suggest how to code them. I find it a very fun challenge

So basically my code actual is:

import ddf.minim.

;;

import ddf.minim.analysis.

Minim minim;

FFT fft;

AudioInput in;

float amp = 20; // used to make signal stronger/weaker

float ampWave = 20*amp;

float avgAudio; // store avg volume globallyfloat bass;

float high;void setup(){

background(255);

size(500, 500);

noStroke();

smooth();minim = new Minim(this); // initalize in setup

in = minim.getLineIn(Minim.STEREO, 512); // audio in + bufferSize 512 or 1024

fft = new FFT(in.bufferSize(), in.sampleRate());

fft.logAverages(22, 3); // 3 = 30, 4 = 40, slices of frequency

}void draw(){

if(keyPressed) {

fft.forward(in.mix); // IMPORTANT! -update for FFT anaylsis

bass = fft.calcAvg(20,300)*amp; // fft.calcAvg(minFreq, maxFreq)

high = fft.calcAvg(300,20000)*amp;

}if(bass > high){

background(255);

fill(0,0,255);

ellipse(width/2, height/2, 50,50);

}else if(high > bass) {

background(255);

fill(255,0,0);

rect(width/2, height/2, 50,50);

}println(bass+" / "+high);

}

and instead of the two background I would like to draw two â€śrandomâ€ť polygonsâ€¦ here on the sketch you can look at it easily:

thanksssss

I think you need to do a lot more drawing to understand your concept â€“ try making a series of images or an animatic.

For example, you suggest that each could have as few as three sidesâ€¦ thatâ€™s always a triangle, and it cannot meet the requirement â€śall angles >= 90â€ť. Similarly, there arenâ€™t closed polygons higher than 4 sides with every angle â€ś<= 90â€ť â€“ for five and up, the average angle must be > 90 â€¦ and to create small angles in a closed 5-plus-agon you must pair them with large angles (e.g. starburst).

I was wandering if can I code something like this:

beginShape();

vertex(random(x), random(y));

vertex(random(x),random(y));

vertex(random(x),random(y));

vertex(random(x),random(y));

endShape(CLOSE);

Should I declare randomX and randomY? And can I say draw random vertex between 4 and 10?

thankssss

solved like this

```
background(255);
noStroke();
fill(255,0,0);
int n_vertex = int(random(3, 7));
beginShape();
for (int i = 0; i < n_vertex; i++) {
vertex(random(width), random(height));
}
endShape(CLOSE);
```

1 Like