OpenGL画蜗型线、心形线、三叶曲线、四叶曲线、螺旋线

这里讲的是一些有趣而美丽的曲线,蜗型线、心形线、三叶曲线、四叶曲线、螺旋线等,都是由圆公式的一些特殊的变化带来的,我们使用了参数极坐标方程来计算曲线路径的点,这些点用做显示弧的逼近折现中直线段的端点。这些曲线主要都是通过圆半径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();//循环执行。
}

  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值