# Mesh ball generation

**URL:** https://discourse.processing.org/t/mesh-ball-generation/4980
**Category:** Coding Questions
**Created:** [October 29, 2018, 11:37am UTC](https://discourse.processing.org/t/mesh-ball-generation/4980 "2018-10-29T11:37:31Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [October 29, 2018, 11:37am UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/1 "2018-10-29T11:37:31Z")

</div>

Im trying to make something like that:

 ![](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/8/84191530afba52a5833758f06cb6a4fa25817079.jpeg)  
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:

```auto
//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:

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

```

---

<div class="post-metadata">

### Author: ![Lexyth](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lexyth/32/7403_2.png) [@Lexyth](https://discourse.processing.org/u/Lexyth)
#### Post date: [October 29, 2018, 2:28pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/2 "2018-10-29T14:28:26Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [October 29, 2018, 4:26pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/3 "2018-10-29T16:26:59Z")

</div>

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…

---

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [October 29, 2018, 4:27pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/4 "2018-10-29T16:27:32Z")

</div>

And in 3d its hard to make

---

<div class="post-metadata">

### Author: ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)
#### Post date: [October 29, 2018, 7:34pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/5 "2018-10-29T19:34:19Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)
#### Post date: [October 29, 2018, 8:43pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/6 "2018-10-29T20:43:08Z")

</div>

Not the way to go for the line ^^

 ![Circle](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/ed9026a4515e0ec99d7140824c832904c506395c.png)

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

```auto
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;
  }
}

```

---

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [October 31, 2018, 10:40am UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/7 "2018-10-31T10:40:17Z")

</div>

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

---

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [October 31, 2018, 10:58am UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/8 "2018-10-31T10:58:08Z")

</div>

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

---

<div class="post-metadata">

### Author: ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)
#### Post date: [November 1, 2018, 2:46pm UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/9 "2018-11-01T14:46:08Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![Darkar25](https://avatars.discourse-cdn.com/v4/letter/d/ecccb3/32.png) [@Darkar25](https://discourse.processing.org/u/Darkar25)
#### Post date: [November 9, 2018, 4:09am UTC](https://discourse.processing.org/t/mesh-ball-generation/4980/10 "2018-11-09T04:09:55Z")

</div>

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