Mesh ball generation

Im trying to make something like that:


I already made dots generation and border circle…but i dont know how to connect all dots between…i need to connect every dot to closest dots…i tried that myself but i got an OutOfBounds exception…
There is code:

//custom method imports
CustomMath math = new CustomMath();
//variable assigment
int intotal = (int)random(25, 50);
int sidetotal = (int)random(10, 20);
int circles = 0;
int i = 0;
float r;
//arrays assgiment
PVector[] temp = new PVector[0];
PVector[] coords = new PVector[0];
PVector[] circle = new PVector[0];
int[] temp2 = new int[0];

void setup() {
  size(displayWidth, displayHeight);
  if(width > height) {
    r = width / TWO_PI;
  } else {
    r = height / TWO_PI;
  }
  background(0);
  translate(width/2, height/2);
  noFill();
  stroke(100, 255, 0);
  strokeWeight(3);
  ellipse(0, 0, r * 2.25 ,r * 2.25);
  drawCircle(sidetotal, (r * 2.25)/2);
  beginShape();

  while (i < intotal) {
      float x = random(-r, r);
      float y = random(-r, r);
      int closest = 0;
  
      double d = (double)x * (double)x + (double)y * (double)y;
      if (d < (double) r * (double) r) {
        circles++;
        int weight = (int)math.compareTo(random(10, 20), intotal, intotal * HALF_PI);
        strokeWeight(weight);
        temp = (PVector[])append(temp, new PVector(x, y));
        for(int n = 0; n < temp.length-1; n++) {
            temp2 = (int[])append(temp2, (int)dist(x, y, temp[n].x, temp[n].y));
        }
        if(temp2.length != 0) {
        closest = min(temp2);
        }
        temp2 = new int[0];
        if(closest - weight*2 > 10) {
          point(x, y);
          coords = (PVector[])append(coords, new PVector(x, y));
          i++;
        }
    }
  }
  endShape();
  connect(coords, circle);
}

void draw() {

}

void drawCircle(float sides, float r) 
{
  noFill(); 
  beginShape(POINTS);
  for (int i = 0; i < sidetotal; i++) {
  int weight2 = (int)math.compareTo(random(15, 25), intotal, intotal * HALF_PI);
  strokeWeight(weight2);
  float angle = 360 / sides + random(15, 20); 
  float x = cos(radians(i * angle )) * r; 
  float y = sin(radians(i * angle )) * r;
  point(x, y);
  circle = (PVector[])append(circle, new PVector(x, y));
}
endShape();
}

void connect(PVector[] inner,PVector[] outer) {
  PVector[] temp;
  PVector[] temp2;
  for(int i = 0; i < inner.length-1; i++) {
    temp = sortPVectorArray(inner[i], inner);
    temp2 = sortPVectorArray(inner[i], outer);
    for(int u = 0; u < temp.length-1; i++) {
      //that line
      if(dist(inner[i].x, inner[i].y, temp[u].x, temp[u].y) > 10) {
        beginShape();
        line(inner[i].x, inner[i].y, temp[u].x, temp[u].y);
        endShape();
      }
    }
    for(PVector vector1 : outer) {
      
    }
  }
}

PVector[] sortPVectorArray(PVector position, PVector[] positions) {
  for(int i = 0; i < positions.length; i++) {
    // Loops through positions
    // Make sure i is not 0 as positions[positions.length] is out of bounds
    if(i != positions.length-1) {
      while (PVector.dist(positions[i+1], position) < PVector.dist(positions[i], position)) {
        PVector temp1 = positions[i+1]; // Assign temp variables
        PVector temp2 = positions[i]; positions[i] = temp1;
        positions[i+1] = temp2; // Swap them around
      }
    }
  }
  return positions;
}

CustomMath class:

public class CustomMath {
  float compareTo(float to,float from, float max) {
    return from/max*to;
  }
}
1 Like

It Would be helpful if you could add on which line the exception was.
And is there a reason to why it is in 2D and you don‘t use 3D?

1 Like

Im using 2d because i making that in 2d in 2 layers…i almost have 1st layer generation…when i complrte 1 layer i would make second…

And in 3d its hard to make

I also think 2D is the way to go because of the border: it’s a perfect circle and all the outside points seat perfectly on this circle.

Now for connection maybe you can try to randomly assign a number of connection to each points, find the closest points to it and connect them. It is not true for all of them but you won’t be able to meet the desired number of connections for each point. So maybe by making the connection for points taken in random order and ignoring the condition if the points already have more connections that it should have will result in an effect like this one?

Not the way to go for the line ^^

If you still wanna see the (super messy) code:

import java.util.Collections;


ArrayList<Point> point, pointCopy;

void setup() {
  size(1024, 1024);
  translate(width / 2, height / 2);

  background(20);

  point = new ArrayList<Point>();
  pointCopy = new ArrayList<Point>();

  // Outside circle
  for (float i = 0; i < TWO_PI; i += random(0.1, 0.3)) {
    float size = getRandomSize(0.8);
    //ellipse(400 * cos(i), 400 * sin(i), size, size);
    point.add(new Point(400 * cos(i), 400 * sin(i), size, true));
  }

  // First row
  for (float i = 0; i < TWO_PI; i += random(0.15, 0.4)) {
    float size = getRandomSize(0.95);
    float r = 350 + random(30);
    //ellipse(r * cos(i), r * sin(i), size, size);
    point.add(new Point(r * cos(i), r * sin(i), size, false));
  }

  // Second row
  for (float i = 0; i < TWO_PI; i += random(0.25, 0.5)) {
    float size = getRandomSize(0.95);
    float r = 300 + random(40);
    //ellipse(r * cos(i), r * sin(i), size, size);
    point.add(new Point(r * cos(i), r * sin(i), size, false));
  }

  // Third row
  for (float i = 0; i < TWO_PI; i += random(0.35, 0.6)) {
    float size = getRandomSize(0.95);
    float r = 200 + random(60);
    //ellipse(r * cos(i), r * sin(i), size, size);
    point.add(new Point(r * cos(i), r * sin(i), size, false));
  }

  // Fourth row
  for (float i = 0; i < TWO_PI; i += random(0.5, 0.75)) {
    float size = getRandomSize(0.95);
    float r = 75 + random(100);
    //ellipse(r * cos(i), r * sin(i), size, size);
    point.add(new Point(r * cos(i), r * sin(i), size, false));
  }

  // Last point
  float size = getRandomSize(0.95);
  float r = random(20);
  float angle = random(TWO_PI);
  //ellipse(r * cos(angle), r * sin(angle), size, size);
  point.add(new Point(r * cos(angle), r * sin(angle), size, false));


  for (int i = 0; i < point.size(); i++) {
    pointCopy.add(new Point(point.get(i).x, point.get(i).y, point.get(i).size, point.get(i).isOutside()));
  }

  Collections.shuffle(point);
  for (int i = 0; i < point.size(); i++) {
    float x = point.get(i).x;
    float y = point.get(i).y;

    for (int j = 0; j < pointCopy.size(); j++) {
      pointCopy.get(j).storeDistanceTo(x, y);
    }

    Collections.sort(pointCopy);

    for (int j = 1; j < pointCopy.size(); j++) {
      if (point.get(i).needConnection() && !point.get(i).isOutside()) {
        stroke(200);
        strokeWeight(1);
        line(point.get(i).x, point.get(i).y, pointCopy.get(j).x, pointCopy.get(j).y);
        point.get(i).addConnection();
      }
    }
  }

  stroke(200);
  strokeWeight(1);
  noFill();
  ellipse(0, 0, 800, 800);

  for (int i = 0; i < point.size(); i++) {
    point.get(i).display();
  }
}


void draw() {
}


int getRandomSize(float x) {
  return random(1) < x ? 8 : 20;
}


class Point implements Comparable<Point> {
  public float x, y, size;

  private boolean outsidePoint;
  private int nbOfConnections, targetConnections;
  private float distance;

  Point (float x, float y, float size, boolean outsidePoint) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.outsidePoint = outsidePoint;
    distance = 0;
    targetConnections = floor(random(3, 6));
    nbOfConnections = 0;
  }

  boolean isOutside() {
    return outsidePoint;
  }

  void display() {
    noStroke();
    fill(200);
    ellipse(x, y, size, size);
  }

  void addConnection() {
    nbOfConnections++;
  }

  boolean needConnection() {
    return nbOfConnections < targetConnections;
  }

  void storeDistanceTo(float x, float y) {
    distance = dist(x, y, this.x, this.y);
  }

  @Override
    public int compareTo(Point other) {
    float result = this.distance - other.distance;
    if (result < 0) {
      return -1;
    }

    if (result > 0) {
      return 1;
    }

    return 0;
  }
}

1 Like

I am made that before posting that code… after comment //that line
Is line where is appearing exception

Yeah.that almost what i wanted…it would be perfect if there will be detection for connection crossing…line over line semms not cool…

Well, it is quite easy to do.

You just need to create a Line class and implements a isIntersecting(Line other) function.

Then instead of just drawing the line, you add them in an arrayList. But before you do so, check if it is crossing one of the previously created line. If not it is good, if so, just move to the next closest point to create the line.

You can also add a display() method to your Line class to simply draw them with a for loop.

1 Like

Uhh…idk how to make that method)))
UPD:i am impkemented that method,it works…no crossing lines…but…some needed lines dissappeared…