(Geomerative) How to test if point is inside a shape?

edited September 2015 in Library Questions

Hi,

I'm starting with Geomerative and I would like to draw some objects inside a shape.

I'm trying to use the contains() method, but I didn't completely understand how that works. When I'm trying to use it, only two points over the contour line passed the tests.

You can find a minimal working example here below.

Thanks for your kind help,

Rufone.

===

import geomerative.*;

RFont rfont;
String myText = "D";
RShape gShape;


//----------------SETUP---------------------------------
void setup()  {
  size(800, 600, P3D);
  background(100);
  lights();


  // init geomerative and get font
  RG.init(this); 
  rfont = new RFont("FreeSans.ttf", 400, CENTER);

  translate(width/2, height/2, 0);

  // we want Isometric 45 degrees view
  //ortho();
  //rotateX(PI/3);
  //rotateZ(-PI/3);


  //CONFIGURE SEGMENT LENGTH AND MODE
  //SETS THE SEGMENT LENGTH BETWEEN TWO POINTS ON A SHAPE/FONT OUTLINE
  RCommand.setSegmentLength(10);//ASSIGN A VALUE OF 10, SO EVERY 10 PIXELS

  RCommand.setSegmentator(RCommand.UNIFORMLENGTH);
  //RCommand.setSegmentator(RCommand.CUBICBEZIERTO);
  //RCommand.setSegmentator(RCommand.ADAPTATIVE);

  //get grouped lettershapes from RFont
  gShape = rfont.toShape(myText);

  stroke(0);
  gShape.draw();

  drawEllipsesInRMesh();

}

//----------------DRAW---------------------------------
void draw()  {

  // we have to set the same space transformations as in setup()
  // otherwise objects are printed displaced
  //translate(width/2, height/2, 0);

  //drawEllipsesInRMesh();

}

// Draw objects inside the RShape
void drawEllipsesInRMesh() {
    float xspace = width/100.0; // If you want 100 rows per screen
    float yspace = height/100.0; // If you want 100 cols per screen
        for(int x=0; x<width; x+=xspace) {
          for(int y=0; y<height; y+=yspace) {
            float xF = float(x);
            float yF = float(y);
            boolean isInShape = gShape.contains(new RPoint(xF, yF));

            if (isInShape) {
              println("x,y,isIN: "+x+","+y+","+isInShape);
              // draw your object at point x, y
              ellipse (xF,yF,20,20);
            }
          }
      }
}
Tagged:

Answers

  • edited September 2015 Answer ✓

    Ok, solved!

    [see picture attached below]

    My bad: I was using the wrong coordinates for x,y in the for loop. I added a function to get the bounding box of the shape, and used the min,max of the bounding box for x,y ranges. Now everything works!

    Updated code attached below.

    ===

    // import Geomerative
    import geomerative.*;
    
    // Import HE_MESH_2014
    import wblut.processing.*;         // hemesh library section for displaying shapes
    import wblut.hemesh.*;             // hemesh library section with main HE_Mesh class 
    import wblut.geom.*;               // hemesh library section with geometry classes
    
    
    RFont rfont;                       // geomerative font used for creating the 3D text
    String myText = "D";               // input text
    RShape gShape;                     // geomerative shape 
    RPoint topLeft, bottomRight;       // points of the bound box of the shape 
    
    
    //----------------SETUP---------------------------------
    void setup()  {
      size(600, 400, P3D);
      smooth(16);
    
      background(100);
      lights();
    
      translate(width/2, 4*height/5); // center the shape
    
      // init geomerative 
      RG.init(this); 
      // set geomerative
      RCommand.setSegmentLength(10);//ASSIGN A VALUE OF 10, SO EVERY 10 PIXELS
      RCommand.setSegmentator(RCommand.UNIFORMLENGTH);
      // and get font
      rfont = new RFont("FreeSans.ttf", 400, CENTER);
    
      //get grouped lettershapes from RFont, and draw it
      gShape = rfont.toShape(myText);
      stroke(0);
      gShape.draw();
    
      //draw bounding box using the two cornerpoints
      getBoundaries();
      noFill();
      rect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
      fill(255);
    
      drawEllipsesInRShape();
    
    }
    
    //----------------DRAW---------------------------------
    void draw()  {
    
    }
    
    //----------------DRAW ELLIPSES WITHIN THE SHAPE---------------------------------
    // Draw objects inside the RShape
    void drawEllipsesInRShape() {
        int n_IN = 0;
        float xspace = width/50.0; // If you want 100 rows per screen
        float yspace = height/50.0; // If you want 100 cols per screen
            for(float x=topLeft.x; x<bottomRight.x; x+=xspace) {
              for(float y=topLeft.y; y<bottomRight.y; y+=yspace) {
                boolean isInShape = gShape.contains(new RPoint(x, y));
                if (isInShape) {
                  ++n_IN;
                  //println("x,y,isIN: "+x+","+y+","+isInShape);
                  // draw your object at point x, y
                  ellipse (x,y,20,20);
                }
              }
          }
          println(n_IN+" points are INSIDE the shape.");
    }
    
    //----------------GET BOUNDARIES---------------------------------
    
    // store boundaries for use later on
    void getBoundaries() {
      //as you can get the corner-points of the bounding box, you can find out exactly where the letters are.
        topLeft = gShape.getTopLeft();
        bottomRight = gShape.getBottomRight();     
        //println("shape boundary - x_min,y_min,z_min: "+min.x+", "+min.y+", "+min.z+" - x_max,y_max,z_max: "+max.x+", "+max.y+", "+max.z);
        println("shape boundary - x_min,y_min: "+topLeft.x+", "+topLeft.y+" - x_max,y_max: "+bottomRight.x+", "+bottomRight.y);
    }
    
Sign In or Register to comment.