Circles with holes or with stroke

I’ve been trying to figure out how to draw circles with holes, or simply with a thick stroke, like this:

I thought ofNextContour() would work with ofCircle(), but it seems it doesn’t, so this was the easiest way I found to achieve it.

  
  
void testApp::circleStroke( int x, int y, int rad, int stroke ){  
    ofBeginShape();  
    int resolution = 22;  
    float angle = 0;  
      
    for( int i=0; i<resolution; i++ ){  
        angle = i*2*PI/resolution;  
        ofVertex(x + rad*sin(angle), y + rad*cos(angle));  
    }  
      
    ofNextContour(true);  
    int rad2 = rad - stroke;  
      
    for( int i=0; i<resolution; i++ ){  
        angle = i*2*PI/resolution;  
        ofVertex(x + rad2*sin(angle), y + rad2*cos(angle));  
    }  
      
	ofEndShape(true);  
}  
  

I’d like to know if there is an easier or more efficient way to do this.

Thanks!

Try using ofNoFill(); before drawing. Calling ofFill() then turns fills back on for 2d drawing.

I have had the same problem in the past, and used a very complex (and Mac-specific) way of generating a stroked polygon from a non-stroked polygon using Apple’s Quartz APIs on Mac OS X:
http://forum.openframeworks.cc/t/how-to-smooth-joints-when-calling-ofsetlinewidth/7278/9
but I think your solution is better for this specific case.
If you are worried about performance, maybe you can use the clever trick that ofCircle uses when drawing using OpenGL? Look at the implementation of ofGLRenderer::drawCircle() in libs/openFrameworks/GL/ofGLRenderer.cpp. It has a fixed resolution (numbers of steps), and has a cached list of positions (the circlePolyline data member) that is scales/moves for each drawCircle function call, so it only needs to perform all the trigonometry calculations once.
Maybe you could cache the points in a similar way?
Or at least generate the points for your two circles using ofPolyline::arc?

you can use an ofPath for this kind of things:

  
  
ofPath circle;  
cricle.arc(center, rad, rad, 0, 360);  
circle.close();  
circle.arc(center, rad2, rad2, 0, 360);  
  
  
circle.draw();  
  

2 Likes

Thanks for all the ideas.

ofPath worked great, arturo. I had no idea of this class: is there any specific example or documentation of it anywhere?

EDIT: However, I did some quick test and using the ofPath method is about twice as slow as doing it with sin and cos functions, as I described in the first post. Just in case someone is interested in performance vs clean code.

I had no idea of this class: is there any specific example or documentation of it anywhere?

no, not yet, but it works more or less the same as beginShape/endShape + it also keeps vectorial information in case you want to draw to for example pdf and you can get the tessellation of the final path as an ofMesh.

Take a look at ofPath.h to see the available methods

A while back I came up with a method to draw ‘thick’ OpenGL circle outlines that could also be drawn with a gradient from opaque to transparent — all without seeing any serious performance drop and working beautifully on iOS. Here’s a screenshot from an iPad using this function;

It takes a number of arguments: number of sides (it can draw shapes with 3+ sides), thickness of outline, % of gradient (sharp or soft edges), colour, size, position and 3D rotation. It involves vertex arrays, so isn’t the most intuitive method to work with (looking back at the code there are a few things I would change!), but it worked well enough for me.

I’m going to clean up the source and post it here. Be right back…

1 Like

Looking forward to see your solution jasonmcdermott.

That’s a really beautiful screen grab right there, I’d be curious to see how you did that without blurring in fragment shaders.

Hello all,

I’ve posted the code over here https://github.com/jasonmcdermott/ofxForums/tree/master/vertexArrayGradientShapes for you to tease apart and use. It’s essentially a set of controls around drawing rotated shapes (setting the number of sides gives us anything from triangles up to circles), rendered quickly and nicely with vertex arrays. I’ve seen up to 50~ of these shapes rendering on an iOS app at around 50 fps.

It all renders as 2D planes in 3D space. I’d love to hear anyone’s thoughts on how to create similar effects with actual 3D shapes!

The screen shot above comes from the iOS app and was ‘drawn’ by the artist who commissioned the app (see here for more http://www.jasonmcdermott.net/portfolio/bright-hearts/). I’ve done my best to recreate it, but I’d encourage you to play around with the diameter, thickness and x/y/z positions to compose new beautiful images…

2 Likes