使用 OpenGL ,分别用点和折线绘制正弦和余弦曲线

        要绘制正余弦曲线,有以下关键几步:

  • 参数化表示

    • 通过将角度 x 作为自变量,可以得到 y 的值,即 y=sin⁡(x)或 y=cos⁡(x)。

    • 将 x 的范围设置为 [−π,π] 即可以完整表示一个正弦或余弦波的周期。

  • 坐标变换

    • 在计算机图形中绘制曲线实现可视化,需要将数学坐标转换为图形坐标。这通常涉及缩放和位移操作。例如,乘以一个缩放因子(如 50)以放大波形,并将坐标平移到可见区域。

  • 逐点绘制

    • 在绘制过程中,可以通过循环遍历角度值,并使用三角函数计算相应的 y 值,随后通过图形API(以OpenGL为例),定义顶点(即每个点的 x 和 y 值)并使用绘制命令( GL_LINE_STRIP表示折线绘制 ; GL_POINTS表示点绘制)来显示这些点。

        代码实现如下:
#include <windows.h>
#include <gl/glut.h>
#include <math.h>
#define PI 3.1415926

static GLsizei iMode = 1;
int winWidth = 500, winHeight = 500;

void init(void) {
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 设置清屏颜色为白色
}

// 窗口大小调整函数
void Reshape(int w, int h) {
    winWidth = w;
    winHeight = h;
    glViewport(0, 0, w, h); // 设置视口为整个窗口
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-250.0, 250.0, -250.0, 250.0); // 根据需要设置二维坐标范围
}

// 绘制正弦曲线的函数
void DrawSineWave(bool isStrip) {
    if (isStrip) {
        glBegin(GL_LINE_STRIP); // 使用折线连接点
    } else {
        glBegin(GL_POINTS); // 仅绘制点
    }

    glColor3f(1.0, 0.0, 0.0); // 设置颜色为红色
    for (float x = -PI; x < PI; x += PI / 90) { // 从 -π 到 π 计算正弦值
        float y = sin(x); // 由于sin函数,需要将角度转化为弧度,步长根据需要进行调整(越小越平滑,这里选用PI/90)
        glVertex2f(50 * x, 50 * y); // 根据 x 计算 y,并进行一定程度的缩放
    }
    glEnd();
}

// 绘制余弦曲线的函数(同上)
void DrawCosineWave(bool isStrip) {
    if (isStrip) {
        glBegin(GL_LINE_STRIP); 
    } else {
        glBegin(GL_POINTS); 
    }

    glColor3f(1.0, 0.0, 0.0);
    for (float x = -PI; x < PI; x += PI / 90) { 
        float y = cos(x);
        glVertex2f(50 * x, 50 * y); 
    }
    glEnd();
}

// 绘制函数
void Display(void) {
    glClear(GL_COLOR_BUFFER_BIT); // 清空颜色缓存
    
    // 绘制坐标轴
    glColor3f(0.0, 0.0, 1.0); // 设置颜色为蓝色
    glBegin(GL_LINES);
    glVertex2f(-250.0, 0);
    glVertex2f(250.0, 0);
    glVertex2f(0, -250.0);
    glVertex2f(0, 250.0);
    glEnd();

    // 根据当前模式绘制正弦或余弦曲线
    switch (iMode) {
        case 1: DrawSineWave(false); break; // 点绘制正弦曲线
        case 2: DrawSineWave(true); break; // 折线绘制正弦曲线
        case 3: DrawCosineWave(false); break; // 点绘制余弦曲线
        case 4: DrawCosineWave(true); break; // 折线绘制余弦曲线
    }

    glutSwapBuffers(); // 交换前后缓存
}

// 菜单处理函数
void ProcessMenu(int value) {
    iMode = value; // 更新当前模式
    glutPostRedisplay(); // 请求重新绘制
}

// 主函数
int main(int argc, char* argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowSize(500, 500); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow("Sine/Cosine Curve");

    // 创建菜单
    int menu = glutCreateMenu(ProcessMenu);
    glutAddMenuEntry("Point to draw sine curve", 1);
    glutAddMenuEntry("Line to draw sine curve", 2);
    glutAddMenuEntry("Point to draw cosine curve", 3);
    glutAddMenuEntry("Line to draw cosine curve", 4);

    init();
    glutReshapeFunc(Reshape);
    glutDisplayFunc(Display); 
    glutAttachMenu(GLUT_RIGHT_BUTTON); // 右键菜单调出菜单
    glutMainLoop(); 
    return 0;
}

        代码效果图:
(右键)菜单显示

 

 

点绘制正弦曲线

 

折线绘制正弦曲线

 

点绘制余弦曲线

 

折线绘制余弦曲线

 

        看上去点绘制和折线绘制的视觉差异不是特别明显,我们以正弦曲线为例再放大看看:

 

 

         

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值