跳出三界之外,不在五行之中,不光有孙悟空,还有他师父
Day3 SFML+直角坐标+多个函数图像
Day3 SFML+直角坐标+多个函数图像

Day3 SFML+直角坐标+多个函数图像

SFML 学习 · Day3

今日目标

  1. 封装数学坐标 ↔ 屏幕坐标转换函数
  2. 同时画:正弦、余弦、二次抛物线
  3. 看懂多函数绘图逻辑,为以后物理化学示意图打底

图像预览

完整代码 day3_func.cpp

#include <SFML/Graphics.hpp>
#include <cmath>

using namespace std;

// 窗口尺寸 + 坐标原点(屏幕中心)
const int WIN_W = 800;
const int WIN_H = 600;
const float OX = WIN_W / 2.0f;
const float OY = WIN_H / 2.0f;

// 缩放系数:1单位数学坐标 = 50像素
const float SCALE = 50.0f;

// 数学坐标 → 屏幕坐标
sf::Vector2f toScreen(float x, float y)
{
    return {
        OX + x * SCALE,
        OY - y * SCALE  // SFML Y向下,数学Y向上,反向
    };
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(WIN_W, WIN_H), L"SFML Day3 多函数绘图");
    window.setFramerateLimit(60);

    // 颜色定义
    sf::Color gridCol(50,50,70);
    sf::Color axisCol(100,200,255);
    sf::Color sinCol(255,70,70);
    sf::Color cosCol(70,255,70);
    sf::Color paraCol(255,255,70);

    while (window.isOpen())
    {
        sf::Event e;
        while (window.pollEvent(e))
        {
            if (e.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color(15,15,25));

        // 1. 画网格
        for (int x = 0; x <= WIN_W; x += 50)
        {
            sf::Vertex l[] = {{{(float)x,0},gridCol}, {{(float)x,WIN_H},gridCol}};
            window.draw(l,2,sf::Lines);
        }
        for (int y = 0; y <= WIN_H; y += 50)
        {
            sf::Vertex l[] = {{{0,(float)y},gridCol}, {{WIN_W,(float)y},gridCol}};
            window.draw(l,2,sf::Lines);
        }

        // 2. 画坐标轴
        sf::Vertex xAxis[] = {toScreen(-8,0), toScreen(8,0)};
        sf::Vertex yAxis[] = {toScreen(0,-6), toScreen(0,6)};
        xAxis[0].color = axisCol;
        xAxis[1].color = axisCol;
        yAxis[0].color = axisCol;
        yAxis[1].color = axisCol;
        window.draw(xAxis,2,sf::Lines);
        window.draw(yAxis,2,sf::Lines);

        // 3. 画正弦函数 y=sin(x)
        for (float x = -7; x < 7; x += 0.02f)
        {
            float y = sin(x);
            sf::CircleShape p(1.4f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(sinCol);
            window.draw(p);
        }

        // 4. 画余弦函数 y=cos(x)
        for (float x = -7; x < 7; x += 0.02f)
        {
            float y = cos(x);
            sf::CircleShape p(1.4f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(cosCol);
            window.draw(p);
        }

        // 5. 画抛物线 y = 0.2*x*x
        for (float x = -5; x < 5; x += 0.02f)
        {
            float y = 0.2f * x * x;
            sf::CircleShape p(1.4f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(paraCol);
            window.draw(p);
        }

        window.display();
    }
    return 0;
}

编译运行

  1. Makefile 追加:
day3: day3_func.o
    $(CXX) $(CXXFLAGS) -o day3 day3_func.o $(LIBS)
  1. 执行:
make day3
./day3

今日核心知识点

  1. 封装 toScreen() 统一坐标转换,以后所有数学/物理图都复用它
  2. SCALE 控制整体放大缩小,改一个数全局生效
  3. 同时绘制三条不同函数,用颜色区分,适合教学演示

运行成功后回复:Day3 三个函数都出来了
我接着带你做 Day4:

  • 鼠标点击拾取数学坐标
  • 键盘按键控制平移、缩放
  • 为后面物理实验、化学示意图做交互铺垫

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注