Number of Sides Required to draw a circle in OpenGL

馋奶兔 提交于 2019-12-06 08:14:10

What you're describing here is effectively a quality factor, which often goes hand-in-hand with error estimates.

A common way we handle this is to calculate the error for a a small portion of the circumference of the circle. The most trivial is to determine the difference in arc length of a slice of the circle, compared to a line segment joining the same two points on the circumference. You could use more effective measures, like difference in area, radius, etc, but this method should be adequate.

Think of an octagon, circumscribed with a perfect circle. In this case, the error is the difference in length of the line between two adjacent points on the octagon, and the arc length of the circle joining those two points.

The arc length is easy enough to calculate: PI * r * theta, where r is your radius, and theta is the angle, in radians, between the two points, assuming you draw lines from each of these points to the center of the circle/polygon. For a closed polygon with n sides, the angle is just (2*PI/n) radians. Let the arc length corresponding to this value of n be equal to A, ie A=2*PI*r/n.

The line length between the two points is easily calculated. Just divide your circle into n isosceles triangles, and each of those into two right-triangles. You know the angle in each right triangle is theta/2 = (2*PI/n)/2 = (PI/n), and the hypotenuse is r. So, you get your equation of sin(PI/n)=x/r, where x is half the length of the line segment joining two adjacent points on your circumscribed polygon. Let this value be B (ie: B=2x, so B=2*r*sin(PI/n)).

Now, just calculate the relative error, E = |A-B| / A (ie: |TrueValue-ApproxValue|/|TrueValue|), and you get a nice little percentage, represented in decimal, of your error vector. You can use the above equations to set a constraint on E (ie: it cannot be greater than some value, say, 1.05), in order for it to "look good".

So, you could write a function that calculates A, B, and E from the above equations, and loop through values of n, and have it stop looping when the calculated value of E is less than your threshold.

I would say that you need to set the number of sides depending on two variables the radius and the zoom (if you allow zoom)

A circle or radius 20 pixels can look ok with 32 to 56 sides, but if you use the same number of sided for a radios of 200 pixels that number of sides will not be enough

numberOfSides = radius * 3

If you allow zoom in and out you will need to do something like this

numberOfSides = radiusOfPaintedCircle * 3

When you zoom in radiusOfPaintedCircle will be bigger that the "property" of the circle being drawn

I've got an algorithm to draw a circle using fixed function opengl, maybe it'll help?

It's hard to know what you mean when you say you want to "approximate a circle using polygon"

You'll notice in my algorithm below that I don't calculate the number of lines needed to draw the circle, I just iterate between 0 .. 2Pi, stepping the angle by 0.1 each time, drawing a line with glVertex2f to that point on the circle, from the previous point.

void Circle::Render()
{   
glLoadIdentity();

glPushMatrix();

    glBegin(GL_LINES);
        glColor3f(_vColour._x, _vColour._y, _vColour._z);
        glVertex3f(_State._position._x, _State._position._y, 0);
        glVertex3f( 
            (_State._position._x + (sinf(_State._angle)*_rRadius)), 
            (_State._position._y + (cosf(_State._angle)*_rRadius)),
            0
        );
    glEnd();

    glTranslatef(_State._position._x, _State._position._y, 0);
    glBegin(GL_LINE_LOOP);
        glColor3f(_vColour._x, _vColour._y, _vColour._z);
        for(float angle = 0.0f; angle < g_k2Pi; angle += 0.1f)
            glVertex2f(sinf(angle)*_rRadius,  cosf(angle)*_rRadius);
    glEnd();                        

glPopMatrix();

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!