How to return values

edited February 2018 in Questions about Code

Hi, I would like to return the coordinates of a polygon, so the next polygon starts at that point. I learned you can't return PVectors, so I will return the x and y values. To begin, I just try to return the x-value.

Polygon Polygon1;
Polygon Polygon2;
float a, b;

void setup() {
  size(600, 600);
  Polygon1 = new Polygon(new PVector(300, 300));
    a = Polygon.endCorner(a);
    Polygon2 = new Polygon(new PVector(a, 200));
  background(204, 100, 30);
}

void draw() {
  Polygon1.build();
  Polygon1.display();
    Polygon2.build();
  Polygon2.display();
  noLoop();
}

class Polygon {
  PVector endCorner = new PVector();
  PVector center = new PVector();
  PVector[] points;

  Polygon(PVector start) {
    center.set(start);
  }

  void build() {
    int numbercorners= int(random(3, 8));                             // calculate all random corners
    float t = 360/numbercorners;                                      // store them als PVectors in an array
    points = new PVector[numbercorners];
    float rotation = random(0, 2 * PI);
    for (int i = 0; i < numbercorners; i++) {
      float xcorner = center.x + sin((radians(i * t)+rotation)) * (20 + random(-8, 10));
      float ycorner = center.y + cos((radians(i * t)+rotation)) * (20 + random(-8, 10));
      points[i] = new PVector(xcorner, ycorner);
    }
  }

  void display() {                                                    // draw the polygon
    beginShape();
    for (int i = 0; i < points.length; i++) {
      vertex(points[i].x, points[i].y);
            a = points[i].x, b= points[i].y;
    }
    endShape(CLOSE);
  }

  float endCorner(float a) {             // This method is ment to pass the last vector
    return a;                            // to be the first vector of a new polygon

    }
}

I get the error "Polygon.endCorner is not a function".

I don't see what I do wrong. I'm using the "a" variable two times, but that's unrelated to the problem I think. Any advice?

Answers

  • ?

    you can return PVector

  • Answer ✓

    For a start, class names should be capitalised - so Polygon is good. Instances of the class shouldn't be capitalised, so Polygon1 is bad, polygon1 is a better name.

    You call Polygon.endCorner, but Polygon is the class name, you really want to call it on the instance of the class so Polygon1.endCorner(), but bearing in mind my first paragraph, polygon1.endCorner()

  • (you can call methods on a class as long as they are declared as static and then they mustn't rely on anything belonging to the instance. Not suitable in this case)

  • I learned you can't return PVectors

    This isn't true btw

  • Yeah, here is a very small (silly) example of returning a PVector:

    void draw(){
      background(192);
      PVector mid = myCenter();
      rect(mid.x, mid.y, 40, 40);
    }
    
    PVector myCenter(){
      PVector pv = new PVector(mouseX, mouseY);
      return pv;
    }
    
  • Thank you Chrisir, koogs and jeremydouglass. I'm renaming the instances like you suggested. I will use a PVector, I thought it wasn't possible because in the Processing Reference under return, it isn't mentioned. I was creating this sketch on OpenProcessing and now I copied it to my computer and I get errors I don't have in the OpenProcessing version ("The constructor Polygon(PVector) doensn't exist"). Once the sketch runs again, I try your suggestions!

  • edited February 2018

    Can I return the value of the last PVector from within "void build" or "void construct"? Because I can't call the "i" variable outside those methods...

    While I ask this, I'm also trying!

    EDIT: NO, because you can't return a value from within "void". I can use the .length variable to get the last vector of the created polygon. point.length-1 (because the elements or an array start at 0)

    I get a nullpointerexeption on that line. Because I called the second polygon, using data from the first, but when that one wasn't drawn yet. I had to move the creation of the second polygon AFTER the first is created (so in the draw-part).

  • edited February 2018

    I got it working! It's not yet what I want, because I don't want them to overlap, so that will be my next challenge :-). (this will be my guide: http://jeffreythompson.org/collision-detection/line-line.php)

    Polygon polygon1;
    Polygon polygon2;
    PVector endcorner, nextpolygon;
    
    void setup() {
      size(600, 600);
    
      background(204, 100, 30);
    }
    
    void draw() {
      polygon1 = new Polygon(new PVector(300, 300));
    
      polygon1.build();
      polygon1.display();
    
      PVector nextpolygon = polygon1.endCorner();
    
      polygon2 = new Polygon(nextpolygon);
      polygon2.build();
      polygon2.display();
      noLoop();
    }
    
    class Polygon {
      PVector endCorner = new PVector();
      PVector firstcorner = new PVector();
      PVector[] points;
    
      Polygon(PVector start) {
        firstcorner.set(start);
      }
    
      void build() {
        int numbercorners= int(random(3, 8));           // select number of corners between 3 and 8
        float t = 360/numbercorners;                    // 
        points = new PVector[numbercorners];            // create an array to store the vectors of each corner
        float rotation = random(0, 2 * PI);             // rotation 
        points[0] = new PVector(firstcorner.x, firstcorner.y);
        for (int i = 1; i < numbercorners; i++) {
          float xcorner = firstcorner.x + sin((radians(i * t)+rotation)) * (20 + random(-8, 10));
          float ycorner = firstcorner.y + cos((radians(i * t)+rotation)) * (20 + random(-8, 10));
          points[i] = new PVector(xcorner, ycorner);
        }
      }
    
      void display() {         // draw the polygon
        beginShape();
        for (int i = 0; i < points.length; i++) {
          vertex(points[i].x, points[i].y);
        }
        endShape(CLOSE);
        ellipse(points[points.length-1].x, points[points.length-1].y, 6, 6);
      }
    
      PVector endCorner() {             // pass the last vector to the next polygon
        int i = int(points.length-1);
        PVector endcorner = new PVector(points[i].x, points[i].y);
        return endcorner;
      }
    }
    
  • Looks like you are on the right track.

    I can see how the return reference could be misleading -- note however that many of the PVector built-in methods return a PVector:

    https://processing.org/reference/PVector.html

    https://processing.org/reference/PVector_setMag_.html

    ...and, as you have figured out, you can return any object, including classes that you create.

  • you can even return arrays or arraylists of pvector

    functions can also receive all this as parameters

Sign In or Register to comment.