OpenGL库中提供了多种图元绘制的函数,但是不知为何圆弧一直不在其中,最近的项目刚好涉及到OpenGL圆与圆弧的绘制,在本篇博客上简单总结。
首先先介绍圆的绘制:这里采用用线段逼近的方法,与其他博主用点逼近相比,线段逼近的复杂度更低一些,同时看上去效果更好。
假设我们用N=100个点产生100条线段去进行圆的逼近,将所计算得到的点用vector保存。详见代码:先定义好PI(圆周率),这是因为标准库中的正弦余弦函数都是用弧度制为参数类型,再定义好Point结构体即可。
const float pi=3.14159; struct Point{ float x,y,z; Point(float _x,float _y,float _z=0.0f):x(_x),y(_y),z(_z){} }; class Draw{ public: void drawCircle(); void drawArc(); void getPointOfCircle(float radius); void getPointOfArc(float radius,float start_angle,float end_angle); private: vector<Point> circle; vector<Point> arc; }; void Draw::getPointOfCircle(float radius){ int N=100; for(int i=0;i<N;i++) circle.push_back(Point(radius*cos(2*pi/N*i),radius*sin(2*pi/N*i))); } void Draw::drawCircle() { glBegin(GL_LINE_LOOP); for(int i=0;i<circle.size();i++){ glVertex3f(circle[i].x, circle[i].y, circle[i].z); } glEnd(); }
接下来讨论圆弧的绘制问题,有了圆的绘制作为基础,圆弧的绘制无非是多了两个参数,起始角度(start_angle)与终止角度(end_angle),需要注意的是起始角度有可能大于终止角度,例如起始角度为300度,终止角度为20度,实际上是要画从300-360度,再从0-20度的圆弧,因此要分别讨论(1)起始角度小于终止角度 (2)起始角度大于终止角度
绘制圆弧还是采用线段逼近的方法,但是注意将圆弧N等分后,角度从起始角度开始计算。详见代码:
void Draw::getPointOfArc(float radius, float start_angle, float end_angle){ int N=100; if(start_angle<end_angle){ float diff=end_angle-start_angle; for(int i=0;i<N;i++) arc.push_back(Point(radius*cos((start_angle+diff/N*i)/360.0*2*pi), radius*cos((start_angle+diff/N*i)/360.0*2*pi))); arc.push_back(Point(radius*cos(end_angle/360.0*2*pi),radius*sin(end_angle/360.0*2*pi)));//将圆弧终点加上 } else{ float diff=end_angle-start_angle+360.0f; for(int i=0;i<N;i++) arc.push_back(Point(radius*cos((start_angle+diff/N*i)/360.0*2*pi), radius*cos((start_angle+diff/N*i)/360.0*2*pi))); arc.push_back(Point(radius*cos(end_angle/360.0*2*pi),radius*sin(end_angle/360.0*2*pi)));//将圆弧终点加上 } } void Draw::drawArc(){ glBegin(GL_LINE_STRIP); for(int i=0;i<arc.size();i++) glVertex3f(arc[i].x, arc[i].y, arc[i].z); glEnd(); }
需要特别注意的是,在计算好圆弧要绘制的点后一定要将圆弧终点的位置加上!这是由于在实际绘制中是无法绘制到终止角度的位置的(由于该点可能根本没有计算,for循环就结束了)。将圆弧终点加上后可以绘制出完整的圆弧。
对于适用性再说明一下:博主的示例程序适用于三维空间中的圆/圆弧的绘制,但是仅讨论了圆心在(0,0,0)处的情况,对于空间中任何一处的圆/圆弧的绘制实际上可以看作是先在圆心为(0,0,0)处的圆/圆弧的绘制,之后通过平移的方式将vector中保存的每个点平移到相应的位置进行绘制即可。
最后,本篇文章创作时间仓促,如有任何内容不妥,请与我联系!