这一节我们继续来实现一些有趣的高级图形,例如蜗形线limacon、心形线cardioid、三叶草threeLeaf、四叶草fourLeaf和螺旋线spiral等漂亮的曲线图形,如下面这些图形所示。
#include <gl/glut.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;
const GLdouble twoPi = 6.283185;
class screenPt{
public:
GLint x, y;
};
typedef enum{limacon=1,cardioid,threeLeaf,fourLeaf,spiral}curveName;//五种图形的枚举
GLsizei winWidth = 600, winHeight = 500;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void lineSegment(screenPt pt1, screenPt pt2)//线段绘制函数,本节也是用曲线细分的方法绘制图形
{
glBegin(GL_LINES);
glVertex2i(pt1.x, pt1.y);
glVertex2i(pt2.x, pt2.y);
glEnd();
}
void drawCurve(GLint curveNum)//核心绘制函数
{
const GLint a = 175, b = 60;//任意的两个曲线参数
GLfloat r, theta, dtheta = 1.0 / float(a);
GLint x0 = 200, y0 = 250;//设置一个任意的屏幕初始坐标
screenPt curvePt[2];
glColor3f(0.0, 0.0, 0.0);
curvePt[0].x = x0;//初始化曲线位置
curvePt[0].y = y0;
switch (curveNum)
{
case limacon:curvePt[0].x += a + b; break;
case cardioid:curvePt[0].x += a + a; break;
case threeLeaf : curvePt[0].x += a; break;
case fourLeaf:curvePt[0].x += a; break;
case spiral:break;
default:
break;
}
theta = dtheta;
while (theta<twoPi)//曲线细分
{
switch (curveNum)//不同的曲线适用不同的极函数
{
case limacon:
r = a*cos(theta) + b; break;
case cardioid:
r = a*(1 + cos(theta)); break;
case threeLeaf:
r = a*cos(3 * theta); break;
case fourLeaf:
r = a*cos(2 * theta);break;
case spiral:
r = (a / 4.0)*theta; break;
default:
break;
}
curvePt[1].x = x0 + r*cos(theta);//绘制细分线段的终点
curvePt[1].y = y0 + r*sin(theta);
lineSegment(curvePt[0], curvePt[1]);//绘制该细分线段
curvePt[0].x = curvePt[1].x;//细分线段的起点坐标更新为终点坐标
curvePt[0].y = curvePt[1].y;
theta += dtheta;//曲线往前绘制
}
}
void displayFcn(void)
{
GLint curveNum;
glClear(GL_COLOR_BUFFER_BIT);
cout << "\nEnter the integer value corresponding to\n";
cout <<"one of the following curve names.\n";
cout << "\Press any other key to exit.\n";
cout << "\n1-limacon,2-cardioid,3-threeLeaf,4-fourLeaf,5-spiral:";
cin >> curveNum;//选择要绘制的曲线类型
if (curveNum == 1 || curveNum == 2 || curveNum == 3 || curveNum == 4 || curveNum == 5)
{
drawCurve(curveNum);//调用曲线绘制函数
}
else
{
exit(0);
}
glFlush();
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
glClear(GL_COLOR_BUFFER_BIT);
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("Draw Curves");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
}