MatLab-cpp

简单的C++绘图库,由OpenGL原生实现,依赖于GLFW创建窗口。

基本使用

#include "matlab.hpp"
#include <cmath>
#include <vector>
#include <iostream>

int main()
{
    using namespace matplot;

    std::vector<float> x = linspace(-4 * acos(-1), 4 * acos(-1), 100);
    std::vector<float> y1, y2;
    for (float xi : x)
    {
        y1.push_back(sin(xi));
        y2.push_back(cos(xi));
    }

    // === 创建一个窗口 ===
    Figure *fig1 = figure();
    auto axes1 = fig1->gca();
    axes1->setTitle("Sine and Cosine Waves");
    axes1->setXLabel("X");
    axes1->setYLabel("Y");
    axes1->grid(true);

    plot(axes1, x, y1, "b-");
    plot(axes1, x, y2, "r--");

    // === 主渲染循环 ===
    std::vector<Figure *> figures = {fig1};
    bool anyOpen = true;

    while (anyOpen)
    {
        anyOpen = false;
        for (auto fig : figures)
        {
            if (fig && fig->window && !glfwWindowShouldClose(fig->window))
            {
                fig->render();
                glfwSwapBuffers(fig->window);
                anyOpen = true;
            }
        }
        glfwPollEvents();
        std::this_thread::sleep_for(std::chrono::milliseconds(16));
    }

    // === 清理 ===
    delete fig1;
    glfwTerminate();

    return 0;
}

作为示波器:

// main.cpp - 示波器功能(固定时间窗口滚动显示)
#include "matlab.hpp"
#include <cmath>
#include <vector>
#include <iostream>

int main()
{
    using namespace matplot;

    Figure *fig = figure();
    auto axes = fig->gca();
    axes->setTitle("Oscilloscope - Real-time Sine Wave");
    axes->setXLabel("Time (s)");
    axes->setYLabel("Amplitude");
    axes->grid(true);
    axes->setDataRange(-1.8f, 1.8f, -3.0f, 3.0f);

    std::vector<float> initX, initY;
    auto line = plot(axes, initX, initY, "r-");
    line->setMaxPoints(50);
    line->setAutoUpdateAxes(false);

    float currentTime = axes->getdataXMin();
    const float dt = 0.05f;
    const float updateTime = 0.02f;
    auto lastUpdateTime = std::chrono::steady_clock::now();
    float b = 0;

    while (!glfwWindowShouldClose(fig->window))
    {
        auto now = std::chrono::steady_clock::now();
        float elapsed = std::chrono::duration<float>(now - lastUpdateTime).count();

        if (elapsed >= updateTime)
        {
            float y = pow(abs(currentTime + b), 0.666666) + 0.9 * pow(3.36 - (abs(currentTime + b) * abs(currentTime + b)), 0.5) * sin(3.141592 * abs(currentTime + b) / 0.1314);
            line->appendData(currentTime, y);
            currentTime += dt;
            if (currentTime >= axes->getdataXMax())
            {
                currentTime = axes->getdataXMin();
            }

            lastUpdateTime = now;
        }

        // 渲染
        fig->render();
        glfwSwapBuffers(fig->window);
        glfwPollEvents();
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }

    delete fig;
    glfwTerminate();
    return 0;
}