How to do this programmatically (Combinatorics?)

A math question. Sorry if it’s a dumb one, but I couldn’t solve it.

I wrote this with this for four points. All possibles lines, no repeating.

        pvline(p0, p1);
        pvline(p0, p2);
        pvline(p0, p3);

        pvline(p1, p2);
        pvline(p1, p3);
        pvline(p2, p3);

pvline() just unpack values from a p5.Vector and apply them:

function pvline(pv1, pv2) {
    line(pv1.x, pv1.y, pv2.x, pv2.y);
}

If I had a lot of points, how to program to draw all possibles lines without repeating. Ho to make the loop? Recursion?

Thanks for any help :wink:

ps: Forgot to mention they are stored in an array points' this.points = [p0, p1, p2, p3 ];`

Hello @vkbr,

I just cooked this up:

The line was joining points in an an array of PVectors around a circle.

Some random points:

:)

3 Likes

Simple and Beautiful!!
thanks!!!

1 Like

Thanks @vkbr for the topic!

Cool!

Adding this to my notes:

Another useful tool:

:)

1 Like

Would be nice to see the source code for those images. I get something totally different when I use the vectors in the original post. I had to scale it up x100 for each point and move it over into the center of the window to get the image shown below. It’s flipped compared to what you would plot on graph paper because the computer screen’s origin is left, top.

int num = 6;
PVector[] v = new PVector[num];

void setup() {
  size(400,400);
  v[0] = new PVector(0,1);
  v[1] = new PVector(0,2);
  v[2] = new PVector(0,3);
  v[3] = new PVector(1,2);
  v[4] = new PVector(1,3);
  v[5] = new PVector(2,3);
  
for(int i = 0; i < num; i++){
  for(int j = i+1; j < num; j++){
    println(i,j);
    line(100 + v[i].x*100, v[i].y*100, 100 + v[j].x*100, v[j].y*100);
  }
}

}

image

:)

1 Like

If you modify this line: float angle = i*TAU/num - TAU/num-1; you can do shapes other than a pentagon.

Effectively the algorithm finds every unique pair of values in a set. I have used this algorithm a lot when performing collision detection.

Since there is no processing to be done when i == num - 1 I have adjusted the outer loop to remove redundant processing.

size(300, 300);
translate(width/2, height/2);
strokeWeight(3);

int num = 5;
PVector [] v = new PVector[num];
float r = 100;

for (int p = 0; p < num; p++) {
  float angle = p * TAU/num;
  v[p] = new PVector(r * cos(angle), r * sin(angle));
}

// Outer loop limit changed 
for (int i = 0; i < num - 1; i++) {
  for (int j = i + 1; j < num; j++) {
    line(v[i].x, v[i].y, v[j].x, v[j].y);
  }
}
3 Likes

Thanks for catching that!

The num was in my final edit of code but not in screen grab:

float angle = i*TAU/num - TAU/4;

The TAU/4 is an offset so 0 degrees is vertical.

:)

Hello,

My original code with some updates from feedback:

/*
 Project:   Polygons
 Author:    GLV
 Date:      2024-06-17
 Version:   1.0.1
*/

size(300, 300);
translate(width/2, height/2);

int num = 7;
PVector [] v = new PVector [num];
int r = 100;

for(int i = 0; i<num; i++)
  {
  float angle = i*TAU/num - TAU/4;  
  float x = round(r*cos(angle));
  float y = round(r*sin(angle)); 
  v[i] = new PVector(x, y);
  }

strokeWeight(3);

for(int i = 0; i < num-1; i++)  // Updated
  {
  for(int j = i+1; j < num; j++)
    {
    println(i,j, ':', v[i], v[j]);
    line(v[i].x, v[i].y, v[j].x, v[j].y);
    }
  }

Rounding was for a clean console output (less decimal places) for the screen grab and rounding to nearest pixel will not be noticeable.

I had some fun with this back when and once again and posted in the gallery:

:)

1 Like