Infinetly thinking


#1

What’s wrong with my code?it seemed to work properly,but when sketch starts,it thinking a lot of time,then app crashes…
Sketch code:

import java.util.Collections;
color clr = color(255, 0, 0);
MeshBall mb = new MeshBall(clr);
color clr2 = color(100, 0, 0);
//MeshBall mb2 = new MeshBall(clr2);
void setup() {
  size(displayWidth, displayHeight, P3D);
  translate(width/2, height/2, 0);
  background(20);
  mb.generate();
  translate(0, 0, -50);
  rotate(90);
  //mb2.generate();
}
void draw() {
  
}
boolean isIntersecting(PVector a, PVector b, PVector c, PVector d, PVector result) {
  // center everything on point "d"
  PVector axis = c.copy().sub(d);
  float axLen = axis.mag();
  axis.normalize();
  PVector workingA = a.copy().sub(d);
  PVector workingB = b.copy().sub(d);
  // create a perpendicular vector to "c-d"
  PVector rightang = new PVector(-axis.y, axis.x);
  // In short: rotate everything so "c-d" becomes the y-axis
  // rightang becomes x-axis
  PVector mappedA = new PVector(workingA.dot(rightang), workingA.dot(axis));
  PVector mappedB = new PVector(workingB.dot(rightang), workingB.dot(axis));
  // More detail: mappedA and -B are projections of "a" and "b" onto the lines
  // "c-d" and "rightang", creating Axis Aligned 2D coordinates
  // Get the axis-aligned segment
  PVector dir = mappedA.sub(mappedB);
  // This is the same math used for 2D axis-aligned-bounding-boxes but only used
  // for one intersection instead of two edges
  // In other words:
  // "How much do we change segment 'a-b's length to reach segment 'c-d'?"
  // Result can be +/- INF, meaning segments are parallel
  // Relying on the floating point to handle div by 0.0 --> INF
  // is implementation dependant. Your hardware may vary.
  float tx = 1.0 / 0.00001;
  if (abs(dir.x) > 0.00001)
  tx = -mappedB.x / dir.x;
  // when the original line segment "a-b" is extended/shortened by tx,
  // the end of that segment is the intersecting point
  PVector inters = a.copy().sub(b).mult(tx).add(b);
  result.set(inters);
  // Segment/segment intersection:
  // Logic is that if the first segment would have to expand or reverse to
  // reach the point at 'inters', then the segments do not cross
  float ty = inters.sub(d).dot(axis);
  boolean intersecting = (tx >= 0) && (tx <= 1.0) && (ty >= 0) && (ty <= axLen);
  return intersecting;
  }

Point class code:

class Point implements Comparable<Point> {
  public float x, y, size;
  public color clr;
  private boolean outsidePoint;
  private int nbOfConnections, targetConnections;
  private float distance;
    Point (float x, float y, float size, color clr, boolean outsidePoint) {
      this.x = x;
      this.y = y;
      this.size = size;
      this.outsidePoint = outsidePoint;
      this.clr = clr;
      distance = 0;
      targetConnections = floor(random(3, 6));
      nbOfConnections = 0;
    }
    boolean isOutside() {
      return outsidePoint;
    }
    void display() {
    noStroke();
    fill(this.clr);
    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;
    }
  }

MeshBall class code:

class MeshBall {
  color clr;
  float size;
  ArrayList<Point> point, pointCopy;
  MeshBall() {
    this.clr = color(0, 0, 0);
  }
  MeshBall(color clr) {
    this.clr = clr;
  }
  void generate() {
    this.size = getRandomSize(0.8);
    point = new ArrayList<Point>();
    pointCopy = new ArrayList<Point>();
    float size = this.size;
    color clr = this.clr;
    //Outside circle
    for (float i = 0; i < TWO_PI; i += random(0.1, 0.3)) {
      //ellipse(400 * cos(i), 400 * sin(i), size, size);
      point.add(new Point(400 * cos(i), 400 * sin(i), size, clr, true));
    }
    // First row
    for (float i = 0; i < TWO_PI; i += random(0.15, 0.4)) {
      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, clr, false));
    }
    // Second row
    for (float i = 0; i < TWO_PI; i += random(0.25, 0.5)) {
      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, clr, false));
    }
    // Third row
    for (float i = 0; i < TWO_PI; i += random(0.35, 0.6)) {
      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, clr, false));
    }
    // Fourth row
    for (float i = 0; i < TWO_PI; i += random(0.5, 0.75)) {
      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, clr, false));
    }
    // Last point
    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, clr, 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).clr, 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()) {
          point.get(i).clr = clr;
            stroke(clr);
            strokeWeight(1);
            boolean colliding = false;
            for(int k = 0; k < point.size(); k++) {
              for(int l = 1; l < pointCopy.size(); l++) {
                if(isIntersecting(new PVector(point.get(i).x, point.get(i).y),new PVector(pointCopy.get(j).x, pointCopy.get(j).y),new PVector(point.get(k).x, point.get(k).y),new PVector(pointCopy.get(l).x, pointCopy.get(l).y),new PVector())) {
                  colliding = true;
                }
              }
            }
            if(!colliding) {
              line(point.get(i).x, point.get(i).y, pointCopy.get(j).x, pointCopy.get(j).y);
              point.get(i).addConnection();
            }
          }
        }
      }
      stroke(clr);
      strokeWeight(1);
      noFill();
      ellipse(0, 0, 800, 800);
      for (int i = 0; i < point.size(); i++) {
        point.get(i).display();
      }
    }
    private int getRandomSize(float x) {
      return random(1) < x ? 8 : 20;
    }
  }

#2

Have you tried debugging your code? Add some println() statements to figure out exactly what’s going on.


#3

No,but i know where exactly it happens
Class:MeshBall
Line:67
When i fixed visual bug in that cycle,sketch started to crash…


#4

Hi @Darkar25, Can you give us a description on what your program is supposed to do ? the sketch runs, take several seconds, but it runs at least on my computer. is there supposed to be some interactivity ?


#5

Hi, @dan850 it runs on pc?hmm…i am testing that on android because i have no access to my pc at now…all interactivity its have:generate new meshball when mouse clicked…if you know how to optimize code,so it will run on android,please tell me…


#6

@Darkar25 Unfortunately, I have not played around with Processing for Android. The best advice i can give you right now is to code a smaller version of this sketch, which can also rule out any memory issues.

Best of luck