Best way to create an annulus? beginContour/endContour not behaving correctly.

I'd like to create an annular shape that can scale well and take different fill colors. It's important that there be an actual hole in the shape rather than just creating something that looks like an annulus using a couple of filled circles. Below is a function that almost does it. The problem is that the code seems to be treating all of the curveVertex() commands as part of a single curve. It draws a line connecting the inner and outer rings. Shouldn't the "beginContour" end the current curve and start a new one?

// Create an annulus, inner radius r, outer radius R
function annulus(r,R) {
 var N = 20;
 fill(255,0,0);
 stroke(0);

 beginShape();
  // Outer circle
  curveVertex(R,0);
  for(var i = 0; i<=N; i++) {
   curveVertex(R*cos(i*2*PI/N),R*sin(i*2*PI/N));
  }
  curveVertex(R,0);

  // Inner circle
  beginContour();
   curveVertex(r,0);
   for(var i = 0; i<=N; i++) {
    curveVertex(r*cos(-i*2*PI/N),r*sin(-i*2*PI/N));
   }
   curveVertex(r,0);
  endContour();

 endShape(CLOSE);
}

Answers

  • trying using only vertex within the contour?

  • Using plain vertex() does give the correct behavior (see code below), but the boundaries of the ellipse are now polygonal instead of smooth. I was hoping to use curveVertex() to smooth out the boundary.

    // Create an annulus, inner radius r, outer radius R
    function vertAnnulus(r,R,c) {
     var N = 20;
     fill(c);
     stroke(0);
    
     beginShape();
      // Outer circle
      for(var i = 0; i<=N; i++) {
       vertex(R*cos(i*2*PI/N),R*sin(i*2*PI/N));
      }
    
      // Inner circle
      beginContour();
       for(var i = 0; i<=N; i++) {
        vertex(r*cos(-i*2*PI/N),r*sin(-i*2*PI/N));
       }
      endContour();
    
     endShape(CLOSE);
    }
    
  • Answer ✓

    you could then say angle += .001; instead of using i or use a bigger N here

  • Very true. Mostly trying to be efficient in case I want to render 100's or 1000's of these annuli.

  • what?

    create one in setup() and then display it whereever you want... you can scale and translate it

  • The sketch I have in mind will involve annuli of many different colors.

  • PShape square;  // The PShape object
    
    void setup() {  
      size(1100, 500);
      // Creating the PShape as a square. The corner 
      // is 0,0 so that the center is at 40,40 
      square = createShape(RECT, 0, 0, 80, 80);
    }
    
    void draw() {
      square.disableStyle();
      fill(255, 2, 222);
      shape(square, 10, 10);
    }
    
  • yoe need to make the thing in setup() and save it there as square or whatever name you choose.

  • Is this a new feature of p5js? My current library is not recognizing PShape and/or createShape.

  • ah, sorry, i was just in processing

  • No worries. You had my hopes up that's all.

  • Also, I'm thinking that using vertex() and just cranking up the resolution is probably the way to go. I kind of assumed that the curveVertex would fill in the intermediate boundary points more efficiently, but I have no real reason to believe that. At some level, those boundary points have to be computed. It's possible it's even more expensive to use curveVertex than just lots of vertices. Thanks for the discussion.

  • Answer ✓

    you're welcome!

  • Hi there

    I've been looking around for news about createShape() and didn't find much. anyone could tell us what's is the best way around and if something is coming our way in the PShape department ?

    cheers

Sign In or Register to comment.