这里讲的是一些有趣而美丽的曲线,蜗型线、心形线、三叶曲线、四叶曲线、螺旋线等,都是由圆公式的一些特殊的变化带来的,我们使用了参数极坐标方程来计算曲线路径的点,这些点用做显示弧的逼近折现中直线段的端点。这些曲线主要都是通过圆半径r的变化来生成。通过元半径的不同,可生成这些图形以及其他各种各样的图形。
下面介绍这些曲线的的原始公式:
首先是圆,众所周知,圆是具有固定圆心(x0,y0)和固定半径r的图形。
x=x0+r*cos(theta)
y=y0+r*sin(theta)(theta是圆心圆上的点与x轴所成的角度)
我们要看的图形都来自圆半径的变化来实现的,x和y的坐标都遵循以上公式。一下公式都使用了参数极坐标方程来计算曲线路径。附有图。
1、蜗形线:
r=a*cos(theta)+b(a、b是常数,theta是角度)
2、心形线:
r=a*(1+cos(theta))(a是常数,theta是角度)
3、三叶曲线:
r=a*cos(3*theta)(a是常数,theta是角度)
4、四叶曲线:
r=a*cos(2*theta)(a是常数,theta是角度)
5、螺旋线:
r=a*theta(a是常数,theta是角度)
附上代码:
#include "stdafx.h"
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
using namespace std;
//screenPt:定义 屏幕上的一个点。
struct screenPt
{
GLint x;
GLint y;
};
//curveName:要画的曲线的名称,1-蜗型线,2-心形线,3-三叶曲线,4-四叶曲线,5-螺旋线。
typedef enum{ limacon = 1, cardioid, threeLeaf, fourLeaf, spiral } curveName;
GLsizei winWidth = 600, winHeight = 500;
//init
//init:初始化屏幕。
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);//设置显示窗口的背景维白色。
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
//lineSegment:画出pt1和pt2之间的直线。
void lineSegment(screenPt pt1, screenPt pt2)
{
glBegin(GL_LINES);
glVertex2i(pt1.x, pt1.y);
glVertex2i(pt2.x, pt2.y);
glEnd();
}
//drawCurve:根据curveNum的值画出对应曲线。
void drawCurve(GLint curveNum)
{
const GLdouble twoPi = 6.283185;
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]是逼近折线的起始位置。
//默认值是:(x0,y0)。
curvePt[0].x = x0;
curvePt[0].y = y0;
switch(curveNum)
{//计算开始逼近折线的起始位置,即theta为0时的曲线上点的x值。
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 / 20.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;
}
}
//displayFcn:显示选项,根据提示选择要显示的曲线。
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);//初始化GLUT。
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置显示模式,使用单缓存和RGB颜色模型。
glutInitWindowPosition(100, 100);//设置窗口位置。
glutInitWindowSize(winWidth, winHeight);//设置窗口大小。
glutCreateWindow("Draw Curves");//创造窗口。
init();//执行初始化程序。
glutDisplayFunc(displayFcn);//将图形信息送往窗口显示。
glutReshapeFunc(winReshapeFcn);//重定义窗口参数。
glutMainLoop();//循环执行。
}