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中保存的每个点平移到相应的位置进行绘制即可。
最后,本篇文章创作时间仓促,如有任何内容不妥,请与我联系!