Best way to create vertices on a circle

Hi everyone,

First off, I am a super noob and I apologize for such a lame question…

I have been trying for hours to draw vertices on a circle that I can manipulate to change the circles shape.

So far… I have been using arc() and ofPolyline. When I set the arcs resolution super low I can see segments. Are those segments vertices I can use or do I need to create vertices on the arc itself? My draw code so far.

ofPolyline polyline1;
ofPoint point1(150,150);
ofCircle(point1, 5);

polyline1.arc(point1, 100, 100, 0, 360, 9);
ofSetColor(ofColor::blue);
polyline1.draw();

cout << &polyline1.getVertices();

Also, If anyone has a better suggestion on how to tackle this I would super appreciate it.

Thank you!

You are definitely on the right track with using arc. You can create a circle using arc, and yes, you can then modify the vertices after you create the circle. The vertices are what define those line segments. Every two consecutive vertices are connected to form a line segment. If you have points A, B, C and D as your vertices in a polyline, then you will have line segments A->B, B->C and C->D.

But a couple amendments to your code:

First, when printing out the vertices in your polyline, try this:

for (int i=0; i<polyline1.size(); i++) {
    cout << polyline1[i] << endl;
}

You can access the vertices of your polyline using the []. This gives you an easy way to both read and change vertices. The way you are doing it is only going to print out the memory location of the vertices in your polyline - something not very comprehensible.

Second, the way you are using arc won’t give you a connected circle. If you look at your vertices, you will see the first and last vertex are duplicates. Your last vertex doesn’t connect to your first vertex, so if you were to shift the vertices on your circle around, you might see something like this:

But I image you want to be able to deform your circle, so that the shape stays together:

Here’s a way to generate a closed circle with arc:

int resolution = 20;
float endAngle = 360.0 - 360.0/resolution;  // Each segment is equal to 360.0/resolution degrees
polyline1.arc(150, 150, 100, 100, 0, endAngle, resolution);
polyline1.setClosed(true);

You want to draw an arc that stops one line segment away from completing the circle. setClosed(true) will tell your polyline to connect that last vertex to the first vertex.

Here’s some sample code to create a circle and deform over time:

ofPolyline modifiedPolyline;
ofPolyline originalPolyline;

void testApp::setup(){
    int resolution = 20;
    float endAngle = 360.0 - 360.0/resolution;
    originalPolyline.arc(150, 150, 100, 100, 0, endAngle, resolution);
    originalPolyline.setClosed(true);

    modifiedPolyline = originalPolyline; // Creates a copy
}

void testApp::draw(){
    modifiedPolyline.draw();
}

void testApp::update(){
    float startAngle = ofGetElapsedTimef() * TWO_PI/2.0; // angle = time (in seconds) * speed (in radians/second)
    for (int i=0; i<originalPolyline.size(); i++) {
        float angleOffset = float(i)/originalPolyline.size() * (4.0*TWO_PI);
        float angle = startAngle + angleOffset;
        float scale = sin(angle*2.0) * 10.0;
        modifiedPolyline[i].x = originalPolyline[i].x + scale * cos(angle);
        modifiedPolyline[i].y = originalPolyline[i].y + scale * sin(angle);
    }
}
1 Like

@mikewesthad perfect answer AGAIN! Thank you so much… this is EXACTLY what I needed. One quick follow up question… it seems arc() only draws straight lines to the next vertex? Is there anyway to keep them smooth curves using curveTo() ?

@andehlu no problem. The way curveTo(...) works is that it generates a bunch of straight line segments that approximate a curve. There aren’t any curved line segments stored in the polyline object - it all gets converted into a series of straight lines. So, I’d recommend pumping up the curveResolution parameter on your arc command. That will make your circle appear more smooth by using a larger number of smaller line segments.

FYI

From Openframeworks reference page, you can specify circleResolution for the last argument of arc() function.

arc(...)void ofPolyline::arc(float x, float y, float radiusX, float radiusY, float angleBegin, float angleEnd, int circleResolution=20)