Loading...
Logo
Processing Forum
I am trying to write a code that draws an ellipse wherever I click on the screen. This is not a problem. Then I want to add some new functionality to that code.

1. Loop through all pts - if distance is less than x, then connect with line.
2. Loop through all pts - draw ellipse at pts based on closest pt (meaning if new pt inserted rescale already drawn ellipses).

Now, I believe that the issue with function 2 is that I don't know how to make it not measure on itself (making shortest distance = 0.0) ... any ideas? I think it might be the structure that isn't really working.

Thanks in advance,

/Claus

Copy code
  1. float[] mPosX = new float[0];     // declare array for x pos
    float[] mPosY = new float[0];     // declare array for y pos
    float[] shortest = new float[0];  // declare array for shortest distance

    int n = 0;

    void setup() {

      // general setup
      size(600, 400);
      background(255);
      smooth();
      fill(0, 100, 200, 20);
      stroke(0);
      strokeWeight(0.25);
      ellipseMode(CENTER);
    }

    void draw() {

      if (n > 0) { // making sure the loop will run only when second pt has been clicked
        for (int i = 0; i < n; i++) {
          float[] distance = new float[n]; // loop through each pt
          for (int j = 0; j < n-1; j++) {        // for each pt, loop through all other pts
            distance[j] = dist(mPosX[i], mPosY[i], mPosX[j], mPosY[j]);
            if (distance[j] < 100) {
              line(mPosX[i], mPosY[i], mPosX[j], mPosY[j]);
            }
          }
          distance = sort(distance);
          shortest = append(shortest, distance[0]);
          ellipse(mPosX[i], mPosY[i], shortest[i], shortest[i]);
        }
      }
    }

    void mousePressed() {

      // write coordinates to array
      mPosX = append(mPosX, mouseX);
      mPosY = append(mPosY, mouseY);
      //println("x" + n + ": " + mPosX[n]);
      //println("y" + n + ": " + mPosY[n]);

      // redim counter
      n = n+1;
    }

Replies(3)

It is a common problem how to compare each element in the array with every other element in the array  and the code below does just that.

I also took the liberty to modify some of the other code for instance you were creating arrays distance and shortest when when all you were interested in was the distance to the nearest point for the ellipse radius. You might need to modify the code somewhat since I didn't fully understand what you meant by

  Loop through all pts - draw ellipse at pts based on closest pt (meaning if new pt inserted rescale already drawn ellipses).
Copy code
  1. void draw() {
  2.   float minDist = Float.MAX_VALUE;
  3.   int nearestPoint = -1;
  4.   float distance = 0;
  5.   if (n > 0) { // making sure the loop will run only when second pt has been clicked   
  6.     for (int i = 0; i < n -1; i++) {    
  7.       for (int j = i + 1; j < n; j++) {        // for each pt, loop through all other pts     
  8.         distance = dist(mPosX[i], mPosY[i], mPosX[j], mPosY[j]);      
  9.         if (distance < 100) {         
  10.           line(mPosX[i], mPosY[i], mPosX[j], mPosY[j]);
  11.           if(distance < minDist) {
  12.             minDist = distance;
  13.             nearestPoint = j; // array index of the nearest point to point[i]
  14.           }
  15.         }
  16.       }   
  17.       ellipse(mPosX[i], mPosY[i], minDist, minDist);
  18.     }
  19.   }
  20. }


Hope this helps.


I would take an object-oriented approach and use ArrayList instead of arrays. This also eliminates to run through two nested loops. One just needs to add the edges for the newly created node.

Your problem above with shortest array is that you increase its size in every frame that is drawn.

Here is my proposal:

Copy code
  1. ArrayList nodes;
  2. ArrayList edges;

  3. void setup() {
  4.   // general setup
  5.   size(600, 400);
  6.   smooth();
  7.   ellipseMode(RADIUS);
  8.   
  9.   nodes = new ArrayList();
  10.   edges = new ArrayList();
  11. }


  12. void draw() {
  13.   background(255);
  14.   // draw the nodes
  15.   for (int i = 0; i < nodes.size(); i++) {
  16.     Node currentNode = (Node) nodes.get(i);
  17.     currentNode.display();
  18.   }
  19.   
  20.   // draw the edges
  21.   for (int i = 0; i < edges.size(); i++) {
  22.     Edge currentEdge = (Edge) edges.get(i);
  23.     currentEdge.display();
  24.   }
  25. }

  26. void mousePressed() {
  27.   nodes.add(new Node(mouseX,mouseY));
  28.   int num_nodes = nodes.size();
  29.   Node new_node = (Node) nodes.get(num_nodes-1);
  30.   if (num_nodes > 1) {
  31.     for (int i = 0; i < num_nodes - 1; i++) {
  32.       Node current_node = (Node) nodes.get(i);
  33.       float d = dist(new_node.x,new_node.y, current_node.x, current_node.y);
  34.       if (d < 100) {
  35.         edges.add(new Edge(new_node, current_node));
  36.         float d_compare = new_node.radius + current_node.radius;   
  37.         if (d < d_compare) {
  38.           float r = d/2;
  39.           new_node.radius = min(r,new_node.radius);
  40.           current_node.radius = min(r,current_node.radius);
  41.         }
  42.       }
  43.     } 
  44.   }
  45. }

  46. class Node {
  47.   float x,y;
  48.   float radius;
  49.   
  50.   Node(float x_init, float y_init) {
  51.     x = x_init;
  52.     y = y_init;
  53.     radius = 99999999;
  54.   }
  55.   
  56.   void display() {
  57.     fill(0, 100, 200, 20);
  58.     stroke(0);
  59.     strokeWeight(0.25);
  60.     if (radius == 99999999) {
  61.       ellipse(x,y,0.1,0.1);
  62.     } else {
  63.       ellipse(x,y,radius,radius);
  64.     }
  65.   }
  66. }


  67. class Edge {
  68.   Node node_start;
  69.   Node node_end;
  70.   
  71.   Edge(Node node_start_init, Node node_end_init) {
  72.     node_start = node_start_init;
  73.     node_end = node_end_init; 
  74.   }
  75.   
  76.   void display() {
  77.     stroke(0);
  78.     strokeWeight(0.25);
  79.     line(node_start.x, node_start.y, node_end.x, node_end.y);
  80.   }
  81. }
Thanks for helping out - I really appreciate it!

The issue of comparing an element in an array with all other elements in an array is something I've been running in to quite a few times, and I never did figure it out, so thank you for addressing that quarks.

And for your object-oriented approach, mbraendle, cheers for that! It is exactly what I was looking for.

This is definitely something I can continue to work on.

Best,
Claus